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 const_zext : llvalue -> lltype -> llvalue (** [const_fptrunc c ty] returns the constant truncation of floating point constant [c] to the smaller floating point type [ty]. See the method [llvm::ConstantExpr::getFPTrunc]. *) -external const_fptrunc : llvalue -> lltype -> llvalue = "LLVMConstFPTrunc" +val const_fptrunc : llvalue -> lltype -> llvalue (** [const_fpext c ty] returns the constant extension of floating point constant [c] to the larger floating point type [ty]. See the method [llvm::ConstantExpr::getFPExt]. *) -external const_fpext : llvalue -> lltype -> llvalue = "LLVMConstFPExt" +val const_fpext : llvalue -> lltype -> llvalue (** [const_uitofp c ty] returns the constant floating point conversion of unsigned integer constant [c] to the floating point type [ty]. See the method [llvm::ConstantExpr::getUIToFP]. *) -external const_uitofp : llvalue -> lltype -> llvalue = "LLVMConstUIToFP" +val const_uitofp : llvalue -> lltype -> llvalue (** [const_sitofp c ty] returns the constant floating point conversion of signed integer constant [c] to the floating point type [ty]. See the method [llvm::ConstantExpr::getSIToFP]. *) -external const_sitofp : llvalue -> lltype -> llvalue = "LLVMConstSIToFP" +val const_sitofp : llvalue -> lltype -> llvalue (** [const_fptoui c ty] returns the constant unsigned integer conversion of floating point constant [c] to integer type [ty]. See the method [llvm::ConstantExpr::getFPToUI]. *) -external const_fptoui : llvalue -> lltype -> llvalue = "LLVMConstFPToUI" +val const_fptoui : llvalue -> lltype -> llvalue (** [const_fptoui c ty] returns the constant unsigned integer conversion of floating point constant [c] to integer type [ty]. See the method [llvm::ConstantExpr::getFPToSI]. *) -external const_fptosi : llvalue -> lltype -> llvalue = "LLVMConstFPToSI" +val const_fptosi : llvalue -> lltype -> llvalue (** [const_ptrtoint c ty] returns the constant integer conversion of pointer constant [c] to integer type [ty]. See the method [llvm::ConstantExpr::getPtrToInt]. *) -external const_ptrtoint : llvalue -> lltype -> llvalue = "LLVMConstPtrToInt" +val const_ptrtoint : llvalue -> lltype -> llvalue (** [const_inttoptr c ty] returns the constant pointer conversion of integer constant [c] to pointer type [ty]. See the method [llvm::ConstantExpr::getIntToPtr]. *) -external const_inttoptr : llvalue -> lltype -> llvalue = "LLVMConstIntToPtr" +val const_inttoptr : llvalue -> lltype -> llvalue (** [const_bitcast c ty] returns the constant bitwise conversion of constant [c] to type [ty] of equal size. See the method [llvm::ConstantExpr::getBitCast]. *) -external const_bitcast : llvalue -> lltype -> llvalue = "LLVMConstBitCast" +val const_bitcast : llvalue -> lltype -> llvalue (** [const_zext_or_bitcast c ty] returns a constant zext or bitwise cast conversion of constant [c] to type [ty]. See the method [llvm::ConstantExpr::getZExtOrBitCast]. *) -external const_zext_or_bitcast : llvalue -> lltype -> llvalue - = "LLVMConstZExtOrBitCast" +val const_zext_or_bitcast : llvalue -> lltype -> llvalue + (** [const_sext_or_bitcast c ty] returns a constant sext or bitwise cast conversion of constant [c] to type [ty]. See the method [llvm::ConstantExpr::getSExtOrBitCast]. *) -external const_sext_or_bitcast : llvalue -> lltype -> llvalue - = "LLVMConstSExtOrBitCast" +val const_sext_or_bitcast : llvalue -> lltype -> llvalue + (** [const_trunc_or_bitcast c ty] returns a constant trunc or bitwise cast conversion of constant [c] to type [ty]. See the method [llvm::ConstantExpr::getTruncOrBitCast]. *) -external const_trunc_or_bitcast : llvalue -> lltype -> llvalue - = "LLVMConstTruncOrBitCast" +val const_trunc_or_bitcast : llvalue -> lltype -> llvalue + (** [const_pointercast c ty] returns a constant bitcast or a pointer-to-int cast conversion of constant [c] to type [ty] of equal size. See the method [llvm::ConstantExpr::getPointerCast]. *) -external const_pointercast : llvalue -> lltype -> llvalue - = "LLVMConstPointerCast" +val const_pointercast : llvalue -> lltype -> llvalue + (** [const_intcast c ty] returns a constant zext, bitcast, or trunc for integer -> integer casts of constant [c] to type [ty]. See the method [llvm::ConstantExpr::getIntCast]. *) -external const_intcast : llvalue -> lltype -> llvalue - = "LLVMConstIntCast" +val const_intcast : llvalue -> lltype -> llvalue + (** [const_fpcast c ty] returns a constant fpext, bitcast, or fptrunc for fp -> fp casts of constant [c] to type [ty]. See the method [llvm::ConstantExpr::getFPCast]. *) -external const_fpcast : llvalue -> lltype -> llvalue - = "LLVMConstFPCast" +val const_fpcast : llvalue -> lltype -> llvalue + (** [const_select cond t f] returns the constant conditional which returns value [t] if the boolean constant [cond] is true and the value [f] otherwise. See the method [llvm::ConstantExpr::getSelect]. *) -external const_select : llvalue -> llvalue -> llvalue -> llvalue - = "LLVMConstSelect" +val const_select : llvalue -> llvalue -> llvalue -> llvalue + (** [const_extractelement vec i] returns the constant [i]th element of constant vector [vec]. [i] must be a constant [i32] value unsigned less than the size of the vector. See the method [llvm::ConstantExpr::getExtractElement]. *) -external const_extractelement : llvalue -> llvalue -> llvalue - = "LLVMConstExtractElement" +val const_extractelement : llvalue -> llvalue -> llvalue + (** [const_insertelement vec v i] returns the constant vector with the same elements as constant vector [v] but the [i]th element replaced by the @@ -977,82 +977,82 @@ elements. [i] must be a constant [i32] value unsigned less than the size of the vector. See the method [llvm::ConstantExpr::getInsertElement]. *) -external const_insertelement : llvalue -> llvalue -> llvalue -> llvalue - = "LLVMConstInsertElement" +val const_insertelement : llvalue -> llvalue -> llvalue -> llvalue + (** [const_shufflevector a b mask] returns a constant [shufflevector]. See the LLVM Language Reference for details on the [shufflevector] instruction. See the method [llvm::ConstantExpr::getShuffleVector]. *) -external const_shufflevector : llvalue -> llvalue -> llvalue -> llvalue - = "LLVMConstShuffleVector" +val const_shufflevector : llvalue -> llvalue -> llvalue -> llvalue + (** [const_extractvalue agg idxs] returns the constant [idxs]th value of constant aggregate [agg]. Each [idxs] must be less than the size of the aggregate. See the method [llvm::ConstantExpr::getExtractValue]. *) -external const_extractvalue : llvalue -> int array -> llvalue - = "llvm_const_extractvalue" +val const_extractvalue : llvalue -> int array -> llvalue + (** [const_insertvalue agg val idxs] inserts the value [val] in the specified indexs [idxs] in the aggegate [agg]. Each [idxs] must be less than the size of the aggregate. See the method [llvm::ConstantExpr::getInsertValue]. *) -external const_insertvalue : llvalue -> llvalue -> int array -> llvalue - = "llvm_const_insertvalue" +val const_insertvalue : llvalue -> llvalue -> int array -> llvalue + (** [const_inline_asm ty asm con side align] inserts a inline assembly string. See the method [llvm::InlineAsm::get]. *) -external const_inline_asm : lltype -> string -> string -> bool -> bool -> +val const_inline_asm : lltype -> string -> string -> bool -> bool -> llvalue - = "llvm_const_inline_asm" + (** [block_address f bb] returns the address of the basic block [bb] in the function [f]. See the method [llvm::BasicBlock::get]. *) -external block_address : llvalue -> llbasicblock -> llvalue = "LLVMBlockAddress" +val block_address : llvalue -> llbasicblock -> llvalue (** {7 Operations on global variables, functions, and aliases (globals)} *) (** [global_parent g] is the enclosing module of the global value [g]. See the method [llvm::GlobalValue::getParent]. *) -external global_parent : llvalue -> llmodule = "LLVMGetGlobalParent" +val global_parent : llvalue -> llmodule (** [is_declaration g] returns [true] if the global value [g] is a declaration only. Returns [false] otherwise. See the method [llvm::GlobalValue::isDeclaration]. *) -external is_declaration : llvalue -> bool = "llvm_is_declaration" +val is_declaration : llvalue -> bool (** [linkage g] returns the linkage of the global value [g]. See the method [llvm::GlobalValue::getLinkage]. *) -external linkage : llvalue -> Linkage.t = "llvm_linkage" +val linkage : llvalue -> Linkage.t (** [set_linkage l g] sets the linkage of the global value [g] to [l]. See the method [llvm::GlobalValue::setLinkage]. *) -external set_linkage : Linkage.t -> llvalue -> unit = "llvm_set_linkage" +val set_linkage : Linkage.t -> llvalue -> unit (** [section g] returns the linker section of the global value [g]. See the method [llvm::GlobalValue::getSection]. *) -external section : llvalue -> string = "llvm_section" +val section : llvalue -> string (** [set_section s g] sets the linker section of the global value [g] to [s]. See the method [llvm::GlobalValue::setSection]. *) -external set_section : string -> llvalue -> unit = "llvm_set_section" +val set_section : string -> llvalue -> unit (** [visibility g] returns the linker visibility of the global value [g]. See the method [llvm::GlobalValue::getVisibility]. *) -external visibility : llvalue -> Visibility.t = "llvm_visibility" +val visibility : llvalue -> Visibility.t (** [set_visibility v g] sets the linker visibility of the global value [g] to [v]. See the method [llvm::GlobalValue::setVisibility]. *) -external set_visibility : Visibility.t -> llvalue -> unit - = "llvm_set_visibility" +val set_visibility : Visibility.t -> llvalue -> unit + (** [alignment g] returns the required alignment of the global value [g]. See the method [llvm::GlobalValue::getAlignment]. *) -external alignment : llvalue -> int = "llvm_alignment" +val alignment : llvalue -> int (** [set_alignment n g] sets the required alignment of the global value [g] to [n] bytes. See the method [llvm::GlobalValue::setAlignment]. *) -external set_alignment : int -> llvalue -> unit = "llvm_set_alignment" +val set_alignment : int -> llvalue -> unit (** {7 Operations on global variables} *) @@ -1061,55 +1061,55 @@ with name [name] in module [m] in the default address space (0). If such a global variable already exists, it is returned. If the type of the existing global differs, then a bitcast to [ty] is returned. *) -external declare_global : lltype -> string -> llmodule -> llvalue - = "llvm_declare_global" +val declare_global : lltype -> string -> llmodule -> llvalue + (** [declare_qualified_global ty name addrspace m] returns a new global variable of type [ty] and with name [name] in module [m] in the address space [addrspace]. If such a global variable already exists, it is returned. If the type of the existing global differs, then a bitcast to [ty] is returned. *) -external declare_qualified_global : lltype -> string -> int -> llmodule -> +val declare_qualified_global : lltype -> string -> int -> llmodule -> llvalue - = "llvm_declare_qualified_global" + (** [define_global name init m] returns a new global with name [name] and initializer [init] in module [m] in the default address space (0). If the named global already exists, it is renamed. See the constructor of [llvm::GlobalVariable]. *) -external define_global : string -> llvalue -> llmodule -> llvalue - = "llvm_define_global" +val define_global : string -> llvalue -> llmodule -> llvalue + (** [define_qualified_global name init addrspace m] returns a new global with name [name] and initializer [init] in module [m] in the address space [addrspace]. If the named global already exists, it is renamed. See the constructor of [llvm::GlobalVariable]. *) -external define_qualified_global : string -> llvalue -> int -> llmodule -> +val define_qualified_global : string -> llvalue -> int -> llmodule -> llvalue - = "llvm_define_qualified_global" + (** [lookup_global name m] returns [Some g] if a global variable with name [name] exists in module [m]. If no such global exists, returns [None]. See the [llvm::GlobalVariable] constructor. *) -external lookup_global : string -> llmodule -> llvalue option - = "llvm_lookup_global" +val lookup_global : string -> llmodule -> llvalue option + (** [delete_global gv] destroys the global variable [gv]. See the method [llvm::GlobalVariable::eraseFromParent]. *) -external delete_global : llvalue -> unit = "llvm_delete_global" +val delete_global : llvalue -> unit (** [global_begin m] returns the first position in the global variable list of the module [m]. [global_begin] and [global_succ] can be used to iterate over the global list in order. See the method [llvm::Module::global_begin]. *) -external global_begin : llmodule -> (llmodule, llvalue) llpos - = "llvm_global_begin" +val global_begin : llmodule -> (llmodule, llvalue) llpos + (** [global_succ gv] returns the global variable list position succeeding [Before gv]. See the method [llvm::Module::global_iterator::operator++]. *) -external global_succ : llvalue -> (llmodule, llvalue) llpos - = "llvm_global_succ" +val global_succ : llvalue -> (llmodule, llvalue) llpos + (** [iter_globals f m] applies function [f] to each of the global variables of module [m] in order. Tail recursive. *) @@ -1123,14 +1123,14 @@ module [m]. [global_end] and [global_pred] can be used to iterate over the global list in reverse. See the method [llvm::Module::global_end]. *) -external global_end : llmodule -> (llmodule, llvalue) llrev_pos - = "llvm_global_end" +val global_end : llmodule -> (llmodule, llvalue) llrev_pos + (** [global_pred gv] returns the global variable list position preceding [After gv]. See the method [llvm::Module::global_iterator::operator--]. *) -external global_pred : llvalue -> (llmodule, llvalue) llrev_pos - = "llvm_global_pred" +val global_pred : llvalue -> (llmodule, llvalue) llrev_pos + (** [rev_iter_globals f m] applies function [f] to each of the global variables of module [m] in reverse order. Tail recursive. *) @@ -1143,37 +1143,37 @@ (** [is_global_constant gv] returns [true] if the global variabile [gv] is a constant. Returns [false] otherwise. See the method [llvm::GlobalVariable::isConstant]. *) -external is_global_constant : llvalue -> bool = "llvm_is_global_constant" +val is_global_constant : llvalue -> bool (** [set_global_constant c gv] sets the global variable [gv] to be a constant if [c] is [true] and not if [c] is [false]. See the method [llvm::GlobalVariable::setConstant]. *) -external set_global_constant : bool -> llvalue -> unit - = "llvm_set_global_constant" +val set_global_constant : bool -> llvalue -> unit + (** [global_initializer gv] returns the initializer for the global variable [gv]. See the method [llvm::GlobalVariable::getInitializer]. *) -external global_initializer : llvalue -> llvalue = "LLVMGetInitializer" +val global_initializer : llvalue -> llvalue (** [set_initializer c gv] sets the initializer for the global variable [gv] to the constant [c]. See the method [llvm::GlobalVariable::setInitializer]. *) -external set_initializer : llvalue -> llvalue -> unit = "llvm_set_initializer" +val set_initializer : llvalue -> llvalue -> unit (** [remove_initializer gv] unsets the initializer for the global variable [gv]. See the method [llvm::GlobalVariable::setInitializer]. *) -external remove_initializer : llvalue -> unit = "llvm_remove_initializer" +val remove_initializer : llvalue -> unit (** [is_thread_local gv] returns [true] if the global variable [gv] is thread-local and [false] otherwise. See the method [llvm::GlobalVariable::isThreadLocal]. *) -external is_thread_local : llvalue -> bool = "llvm_is_thread_local" +val is_thread_local : llvalue -> bool (** [set_thread_local c gv] sets the global variable [gv] to be thread local if [c] is [true] and not otherwise. See the method [llvm::GlobalVariable::setThreadLocal]. *) -external set_thread_local : bool -> llvalue -> unit = "llvm_set_thread_local" +val set_thread_local : bool -> llvalue -> unit (** {7 Operations on aliases} *) @@ -1181,8 +1181,8 @@ (** [add_alias m t a n] inserts an alias in the module [m] with the type [t] and the aliasee [a] with the name [n]. See the constructor for [llvm::GlobalAlias]. *) -external add_alias : llmodule -> lltype -> llvalue -> string -> llvalue - = "llvm_add_alias" +val add_alias : llmodule -> lltype -> llvalue -> string -> llvalue + (** {7 Operations on functions} *) @@ -1191,38 +1191,38 @@ with name [name] in module [m]. If such a function already exists, it is returned. If the type of the existing function differs, then a bitcast to [ty] is returned. *) -external declare_function : string -> lltype -> llmodule -> llvalue - = "llvm_declare_function" +val declare_function : string -> lltype -> llmodule -> llvalue + (** [define_function name ty m] creates a new function with name [name] and type [ty] in module [m]. If the named function already exists, it is renamed. An entry basic block is created in the function. See the constructor of [llvm::GlobalVariable]. *) -external define_function : string -> lltype -> llmodule -> llvalue - = "llvm_define_function" +val define_function : string -> lltype -> llmodule -> llvalue + (** [lookup_function name m] returns [Some f] if a function with name [name] exists in module [m]. If no such function exists, returns [None]. See the method [llvm::Module] constructor. *) -external lookup_function : string -> llmodule -> llvalue option - = "llvm_lookup_function" +val lookup_function : string -> llmodule -> llvalue option + (** [delete_function f] destroys the function [f]. See the method [llvm::Function::eraseFromParent]. *) -external delete_function : llvalue -> unit = "llvm_delete_function" +val delete_function : llvalue -> unit (** [function_begin m] returns the first position in the function list of the module [m]. [function_begin] and [function_succ] can be used to iterate over the function list in order. See the method [llvm::Module::begin]. *) -external function_begin : llmodule -> (llmodule, llvalue) llpos - = "llvm_function_begin" +val function_begin : llmodule -> (llmodule, llvalue) llpos + (** [function_succ gv] returns the function list position succeeding [Before gv]. See the method [llvm::Module::iterator::operator++]. *) -external function_succ : llvalue -> (llmodule, llvalue) llpos - = "llvm_function_succ" +val function_succ : llvalue -> (llmodule, llvalue) llpos + (** [iter_functions f m] applies function [f] to each of the functions of module [m] in order. Tail recursive. *) @@ -1236,13 +1236,13 @@ the module [m]. [function_end] and [function_pred] can be used to iterate over the function list in reverse. See the method [llvm::Module::end]. *) -external function_end : llmodule -> (llmodule, llvalue) llrev_pos - = "llvm_function_end" +val function_end : llmodule -> (llmodule, llvalue) llrev_pos + (** [function_pred gv] returns the function list position preceding [After gv]. See the method [llvm::Module::iterator::operator--]. *) -external function_pred : llvalue -> (llmodule, llvalue) llrev_pos - = "llvm_function_pred" +val function_pred : llvalue -> (llmodule, llvalue) llrev_pos + (** [rev_iter_functions f fn] applies function [f] to each of the functions of module [m] in reverse order. Tail recursive. *) @@ -1254,26 +1254,26 @@ (** [is_intrinsic f] returns true if the function [f] is an intrinsic. See the method [llvm::Function::isIntrinsic]. *) -external is_intrinsic : llvalue -> bool = "llvm_is_intrinsic" +val is_intrinsic : llvalue -> bool (** [function_call_conv f] returns the calling convention of the function [f]. See the method [llvm::Function::getCallingConv]. *) -external function_call_conv : llvalue -> int = "llvm_function_call_conv" +val function_call_conv : llvalue -> int (** [set_function_call_conv cc f] sets the calling convention of the function [f] to the calling convention numbered [cc]. See the method [llvm::Function::setCallingConv]. *) -external set_function_call_conv : int -> llvalue -> unit - = "llvm_set_function_call_conv" +val set_function_call_conv : int -> llvalue -> unit + (** [gc f] returns [Some name] if the function [f] has a garbage collection algorithm specified and [None] otherwise. See the method [llvm::Function::getGC]. *) -external gc : llvalue -> string option = "llvm_gc" +val gc : llvalue -> string option (** [set_gc gc f] sets the collection algorithm for the function [f] to [gc]. See the method [llvm::Function::setGC]. *) -external set_gc : string option -> llvalue -> unit = "llvm_set_gc" +val set_gc : string option -> llvalue -> unit (** [add_function_attr f a] adds attribute [a] to the return type of function [f]. *) @@ -1287,26 +1287,26 @@ (** [params f] returns the parameters of function [f]. See the method [llvm::Function::getArgumentList]. *) -external params : llvalue -> llvalue array = "llvm_params" +val params : llvalue -> llvalue array (** [param f n] returns the [n]th parameter of function [f]. See the method [llvm::Function::getArgumentList]. *) -external param : llvalue -> int -> llvalue = "llvm_param" +val param : llvalue -> int -> llvalue (** [param_parent p] returns the parent function that owns the parameter. See the method [llvm::Argument::getParent]. *) -external param_parent : llvalue -> llvalue = "LLVMGetParamParent" +val param_parent : llvalue -> llvalue (** [param_begin f] returns the first position in the parameter list of the function [f]. [param_begin] and [param_succ] can be used to iterate over the parameter list in order. See the method [llvm::Function::arg_begin]. *) -external param_begin : llvalue -> (llvalue, llvalue) llpos = "llvm_param_begin" +val param_begin : llvalue -> (llvalue, llvalue) llpos (** [param_succ bb] returns the parameter list position succeeding [Before bb]. See the method [llvm::Function::arg_iterator::operator++]. *) -external param_succ : llvalue -> (llvalue, llvalue) llpos = "llvm_param_succ" +val param_succ : llvalue -> (llvalue, llvalue) llpos (** [iter_params f fn] applies function [f] to each of the parameters of function [fn] in order. Tail recursive. *) @@ -1320,12 +1320,12 @@ the function [f]. [param_end] and [param_pred] can be used to iterate over the parameter list in reverse. See the method [llvm::Function::arg_end]. *) -external param_end : llvalue -> (llvalue, llvalue) llrev_pos = "llvm_param_end" +val param_end : llvalue -> (llvalue, llvalue) llrev_pos (** [param_pred gv] returns the function list position preceding [After gv]. See the method [llvm::Function::arg_iterator::operator--]. *) -external param_pred : llvalue -> (llvalue, llvalue) llrev_pos - = "llvm_param_pred" +val param_pred : llvalue -> (llvalue, llvalue) llrev_pos + (** [rev_iter_params f fn] applies function [f] to each of the parameters of function [fn] in reverse order. Tail recursive. *) @@ -1342,51 +1342,51 @@ val remove_param_attr : llvalue -> Attribute.t -> unit (** [set_param_alignment p a] set the alignment of parameter [p] to [a]. *) -external set_param_alignment : llvalue -> int -> unit - = "llvm_set_param_alignment" +val set_param_alignment : llvalue -> int -> unit + (** {7 Operations on basic blocks} *) (** [basic_blocks fn] returns the basic blocks of the function [f]. See the method [llvm::Function::getBasicBlockList]. *) -external basic_blocks : llvalue -> llbasicblock array = "llvm_basic_blocks" +val basic_blocks : llvalue -> llbasicblock array (** [entry_block fn] returns the entry basic block of the function [f]. See the method [llvm::Function::getEntryBlock]. *) -external entry_block : llvalue -> llbasicblock = "LLVMGetEntryBasicBlock" +val entry_block : llvalue -> llbasicblock (** [delete_block bb] deletes the basic block [bb]. See the method [llvm::BasicBlock::eraseFromParent]. *) -external delete_block : llbasicblock -> unit = "llvm_delete_block" +val delete_block : llbasicblock -> unit (** [append_block c name f] creates a new basic block named [name] at the end of function [f] in the context [c]. See the constructor of [llvm::BasicBlock]. *) -external append_block : llcontext -> string -> llvalue -> llbasicblock - = "llvm_append_block" +val append_block : llcontext -> string -> llvalue -> llbasicblock + (** [insert_block c name bb] creates a new basic block named [name] before the basic block [bb] in the context [c]. See the constructor of [llvm::BasicBlock]. *) -external insert_block : llcontext -> string -> llbasicblock -> llbasicblock - = "llvm_insert_block" +val insert_block : llcontext -> string -> llbasicblock -> llbasicblock + (** [block_parent bb] returns the parent function that owns the basic block. See the method [llvm::BasicBlock::getParent]. *) -external block_parent : llbasicblock -> llvalue = "LLVMGetBasicBlockParent" +val block_parent : llbasicblock -> llvalue (** [block_begin f] returns the first position in the basic block list of the function [f]. [block_begin] and [block_succ] can be used to iterate over the basic block list in order. See the method [llvm::Function::begin]. *) -external block_begin : llvalue -> (llvalue, llbasicblock) llpos - = "llvm_block_begin" +val block_begin : llvalue -> (llvalue, llbasicblock) llpos + (** [block_succ bb] returns the basic block list position succeeding [Before bb]. See the method [llvm::Function::iterator::operator++]. *) -external block_succ : llbasicblock -> (llvalue, llbasicblock) llpos - = "llvm_block_succ" +val block_succ : llbasicblock -> (llvalue, llbasicblock) llpos + (** [iter_blocks f fn] applies function [f] to each of the basic blocks of function [fn] in order. Tail recursive. *) @@ -1400,13 +1400,13 @@ the function [f]. [block_end] and [block_pred] can be used to iterate over the basic block list in reverse. See the method [llvm::Function::end]. *) -external block_end : llvalue -> (llvalue, llbasicblock) llrev_pos - = "llvm_block_end" +val block_end : llvalue -> (llvalue, llbasicblock) llrev_pos + (** [block_pred gv] returns the function list position preceding [After gv]. See the method [llvm::Function::iterator::operator--]. *) -external block_pred : llbasicblock -> (llvalue, llbasicblock) llrev_pos - = "llvm_block_pred" +val block_pred : llbasicblock -> (llvalue, llbasicblock) llrev_pos + (** [rev_iter_blocks f fn] applies function [f] to each of the basic blocks of function [fn] in reverse order. Tail recursive. *) @@ -1417,34 +1417,34 @@ val fold_right_blocks : (llbasicblock -> 'a -> 'a) -> llvalue -> 'a -> 'a (** [value_of_block bb] losslessly casts [bb] to an [llvalue]. *) -external value_of_block : llbasicblock -> llvalue = "LLVMBasicBlockAsValue" +val value_of_block : llbasicblock -> llvalue (** [value_is_block v] returns [true] if the value [v] is a basic block and [false] otherwise. Similar to [llvm::isa]. *) -external value_is_block : llvalue -> bool = "llvm_value_is_block" +val value_is_block : llvalue -> bool (** [block_of_value v] losslessly casts [v] to an [llbasicblock]. *) -external block_of_value : llvalue -> llbasicblock = "LLVMValueAsBasicBlock" +val block_of_value : llvalue -> llbasicblock (** {7 Operations on instructions} *) (** [instr_parent i] is the enclosing basic block of the instruction [i]. See the method [llvm::Instruction::getParent]. *) -external instr_parent : llvalue -> llbasicblock = "LLVMGetInstructionParent" +val instr_parent : llvalue -> llbasicblock (** [instr_begin bb] returns the first position in the instruction list of the basic block [bb]. [instr_begin] and [instr_succ] can be used to iterate over the instruction list in order. See the method [llvm::BasicBlock::begin]. *) -external instr_begin : llbasicblock -> (llbasicblock, llvalue) llpos - = "llvm_instr_begin" +val instr_begin : llbasicblock -> (llbasicblock, llvalue) llpos + (** [instr_succ i] returns the instruction list position succeeding [Before i]. See the method [llvm::BasicBlock::iterator::operator++]. *) -external instr_succ : llvalue -> (llbasicblock, llvalue) llpos - = "llvm_instr_succ" +val instr_succ : llvalue -> (llbasicblock, llvalue) llpos + (** [iter_instrs f bb] applies function [f] to each of the instructions of basic block [bb] in order. Tail recursive. *) @@ -1458,13 +1458,13 @@ basic block [bb]. [instr_end] and [instr_pred] can be used to iterate over the instruction list in reverse. See the method [llvm::BasicBlock::end]. *) -external instr_end : llbasicblock -> (llbasicblock, llvalue) llrev_pos - = "llvm_instr_end" +val instr_end : llbasicblock -> (llbasicblock, llvalue) llrev_pos + (** [instr_pred i] returns the instruction list position preceding [After i]. See the method [llvm::BasicBlock::iterator::operator--]. *) -external instr_pred : llvalue -> (llbasicblock, llvalue) llrev_pos - = "llvm_instr_pred" +val instr_pred : llvalue -> (llbasicblock, llvalue) llrev_pos + (** [fold_right_instrs f bb init] is [f (... (f init fN) ...) f1] where [f1,...,fN] are the instructions of basic block [bb]. Tail recursive. *) @@ -1477,16 +1477,16 @@ instruction [ci], which may be one of the values from the module {!CallConv}. See the method [llvm::CallInst::getCallingConv] and [llvm::InvokeInst::getCallingConv]. *) -external instruction_call_conv: llvalue -> int - = "llvm_instruction_call_conv" +val instruction_call_conv: llvalue -> int + (** [set_instruction_call_conv cc ci] sets the calling convention for the call or invoke instruction [ci] to the integer [cc], which can be one of the values from the module {!CallConv}. See the method [llvm::CallInst::setCallingConv] and [llvm::InvokeInst::setCallingConv]. *) -external set_instruction_call_conv: int -> llvalue -> unit - = "llvm_set_instruction_call_conv" +val set_instruction_call_conv: int -> llvalue -> unit + (** [add_instruction_param_attr ci i a] adds attribute [a] to the [i]th parameter of the call or invoke instruction [ci]. [i]=0 denotes the return @@ -1503,23 +1503,23 @@ (** [is_tail_call ci] is [true] if the call instruction [ci] is flagged as eligible for tail call optimization, [false] otherwise. See the method [llvm::CallInst::isTailCall]. *) -external is_tail_call : llvalue -> bool = "llvm_is_tail_call" +val is_tail_call : llvalue -> bool (** [set_tail_call tc ci] flags the call instruction [ci] as eligible for tail call optimization if [tc] is [true], clears otherwise. See the method [llvm::CallInst::setTailCall]. *) -external set_tail_call : bool -> llvalue -> unit = "llvm_set_tail_call" +val set_tail_call : bool -> llvalue -> unit (** {7 Operations on phi nodes} *) (** [add_incoming (v, bb) pn] adds the value [v] to the phi node [pn] for use with branches from [bb]. See the method [llvm::PHINode::addIncoming]. *) -external add_incoming : (llvalue * llbasicblock) -> llvalue -> unit - = "llvm_add_incoming" +val add_incoming : (llvalue * llbasicblock) -> llvalue -> unit + (** [incoming pn] returns the list of value-block pairs for phi node [pn]. See the method [llvm::PHINode::getIncomingValue]. *) -external incoming : llvalue -> (llvalue * llbasicblock) list = "llvm_incoming" +val incoming : llvalue -> (llvalue * llbasicblock) list @@ -1529,7 +1529,7 @@ the context [context]. It is invalid to use this builder until its position is set with {!position_before} or {!position_at_end}. See the constructor for [llvm::LLVMBuilder]. *) -external builder : llcontext -> llbuilder = "llvm_builder" +val builder : llcontext -> llbuilder (** [builder_at ip] creates an instruction builder positioned at [ip]. See the constructor for [llvm::LLVMBuilder]. *) @@ -1546,8 +1546,8 @@ (** [position_builder ip bb] moves the instruction builder [bb] to the position [ip]. See the constructor for [llvm::LLVMBuilder]. *) -external position_builder : (llbasicblock, llvalue) llpos -> llbuilder -> unit - = "llvm_position_builder" +val position_builder : (llbasicblock, llvalue) llpos -> llbuilder -> unit + (** [position_before ins b] moves the instruction builder [b] to before the instruction [isn]. See the method [llvm::LLVMBuilder::SetInsertPoint]. *) @@ -1561,38 +1561,38 @@ positioned to insert into. Raises [Not_Found] if the instruction builder is uninitialized. See the method [llvm::LLVMBuilder::GetInsertBlock]. *) -external insertion_block : llbuilder -> llbasicblock = "llvm_insertion_block" +val insertion_block : llbuilder -> llbasicblock (** [insert_into_builder i name b] inserts the specified instruction [i] at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::Insert]. *) -external insert_into_builder : llvalue -> string -> llbuilder -> unit - = "llvm_insert_into_builder" +val insert_into_builder : llvalue -> string -> llbuilder -> unit + (** {7 Metadata} *) (** [set_current_debug_location b md] sets the current debug location [md] in the builder [b]. See the method [llvm::IRBuilder::SetDebugLocation]. *) -external set_current_debug_location : llbuilder -> llvalue -> unit - = "llvm_set_current_debug_location" +val set_current_debug_location : llbuilder -> llvalue -> unit + (** [clear_current_debug_location b] clears the current debug location in the builder [b]. *) -external clear_current_debug_location : llbuilder -> unit - = "llvm_clear_current_debug_location" +val clear_current_debug_location : llbuilder -> unit + (** [current_debug_location b] returns the current debug location, or None if none is currently set. See the method [llvm::IRBuilder::GetDebugLocation]. *) -external current_debug_location : llbuilder -> llvalue option - = "llvm_current_debug_location" +val current_debug_location : llbuilder -> llvalue option + (** [set_inst_debug_location b i] sets the current debug location of the builder [b] to the instruction [i]. See the method [llvm::IRBuilder::SetInstDebugLocation]. *) -external set_inst_debug_location : llbuilder -> llvalue -> unit - = "llvm_set_inst_debug_location" +val set_inst_debug_location : llbuilder -> llvalue -> unit + (** {7 Terminators} *) @@ -1600,81 +1600,81 @@ [ret void] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateRetVoid]. *) -external build_ret_void : llbuilder -> llvalue = "llvm_build_ret_void" +val build_ret_void : llbuilder -> llvalue (** [build_ret v b] creates a [ret %v] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateRet]. *) -external build_ret : llvalue -> llbuilder -> llvalue = "llvm_build_ret" +val build_ret : llvalue -> llbuilder -> llvalue (** [build_aggregate_ret vs b] creates a [ret {...} { %v1, %v2, ... } ] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateAggregateRet]. *) -external build_aggregate_ret : llvalue array -> llbuilder -> llvalue - = "llvm_build_aggregate_ret" +val build_aggregate_ret : llvalue array -> llbuilder -> llvalue + (** [build_br bb b] creates a [br %bb] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateBr]. *) -external build_br : llbasicblock -> llbuilder -> llvalue = "llvm_build_br" +val build_br : llbasicblock -> llbuilder -> llvalue (** [build_cond_br cond tbb fbb b] creates a [br %cond, %tbb, %fbb] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateCondBr]. *) -external build_cond_br : llvalue -> llbasicblock -> llbasicblock -> llbuilder -> - llvalue = "llvm_build_cond_br" +val build_cond_br : llvalue -> llbasicblock -> llbasicblock -> llbuilder -> + llvalue (** [build_switch case elsebb count b] creates an empty [switch %case, %elsebb] instruction at the position specified by the instruction builder [b] with space reserved for [count] cases. See the method [llvm::LLVMBuilder::CreateSwitch]. *) -external build_switch : llvalue -> llbasicblock -> int -> llbuilder -> llvalue - = "llvm_build_switch" +val build_switch : llvalue -> llbasicblock -> int -> llbuilder -> llvalue + (** [add_case sw onval bb] causes switch instruction [sw] to branch to [bb] when its input matches the constant [onval]. See the method [llvm::SwitchInst::addCase]. **) -external add_case : llvalue -> llvalue -> llbasicblock -> unit - = "llvm_add_case" +val add_case : llvalue -> llvalue -> llbasicblock -> unit + (** [build_indirect_br addr count b] creates a [indirectbr %addr] instruction at the position specified by the instruction builder [b] with space reserved for [count] destinations. See the method [llvm::LLVMBuilder::CreateIndirectBr]. *) -external build_indirect_br : llvalue -> int -> llbuilder -> llvalue - = "llvm_build_indirect_br" +val build_indirect_br : llvalue -> int -> llbuilder -> llvalue + (** [add_destination br bb] adds the basic block [bb] as a possible branch location for the indirectbr instruction [br]. See the method [llvm::IndirectBrInst::addDestination]. **) -external add_destination : llvalue -> llbasicblock -> unit - = "llvm_add_destination" +val add_destination : llvalue -> llbasicblock -> unit + (** [build_invoke fn args tobb unwindbb name b] creates an [%name = invoke %fn(args) to %tobb unwind %unwindbb] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateInvoke]. *) -external build_invoke : llvalue -> llvalue array -> llbasicblock -> +val build_invoke : llvalue -> llvalue array -> llbasicblock -> llbasicblock -> string -> llbuilder -> llvalue - = "llvm_build_invoke_bc" "llvm_build_invoke_nat" + (** [build_unwind b] creates an [unwind] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateUnwind]. *) -external build_unwind : llbuilder -> llvalue = "llvm_build_unwind" +val build_unwind : llbuilder -> llvalue (** [build_unreachable b] creates an [unreachable] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateUnwind]. *) -external build_unreachable : llbuilder -> llvalue = "llvm_build_unreachable" +val build_unreachable : llbuilder -> llvalue (** {7 Arithmetic} *) @@ -1683,216 +1683,216 @@ [%name = add %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateAdd]. *) -external build_add : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_add" +val build_add : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** [build_nsw_add x y name b] creates a [%name = nsw add %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateNSWAdd]. *) -external build_nsw_add : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_nsw_add" +val build_nsw_add : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** [build_nuw_add x y name b] creates a [%name = nuw add %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateNUWAdd]. *) -external build_nuw_add : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_nuw_add" +val build_nuw_add : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** [build_fadd x y name b] creates a [%name = fadd %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateFAdd]. *) -external build_fadd : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_fadd" +val build_fadd : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** [build_sub x y name b] creates a [%name = sub %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateSub]. *) -external build_sub : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_sub" +val build_sub : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** [build_nsw_sub x y name b] creates a [%name = nsw sub %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateNSWSub]. *) -external build_nsw_sub : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_nsw_sub" +val build_nsw_sub : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** [build_nuw_sub x y name b] creates a [%name = nuw sub %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateNUWSub]. *) -external build_nuw_sub : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_nuw_sub" +val build_nuw_sub : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** [build_fsub x y name b] creates a [%name = fsub %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateFSub]. *) -external build_fsub : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_fsub" +val build_fsub : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** [build_mul x y name b] creates a [%name = mul %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateMul]. *) -external build_mul : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_mul" +val build_mul : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** [build_nsw_mul x y name b] creates a [%name = nsw mul %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateNSWMul]. *) -external build_nsw_mul : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_nsw_mul" +val build_nsw_mul : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** [build_nuw_mul x y name b] creates a [%name = nuw mul %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateNUWMul]. *) -external build_nuw_mul : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_nuw_mul" +val build_nuw_mul : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** [build_fmul x y name b] creates a [%name = fmul %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateFMul]. *) -external build_fmul : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_fmul" +val build_fmul : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** [build_udiv x y name b] creates a [%name = udiv %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateUDiv]. *) -external build_udiv : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_udiv" +val build_udiv : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** [build_sdiv x y name b] creates a [%name = sdiv %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateSDiv]. *) -external build_sdiv : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_sdiv" +val build_sdiv : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** [build_exact_sdiv x y name b] creates a [%name = exact sdiv %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateExactSDiv]. *) -external build_exact_sdiv : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_exact_sdiv" +val build_exact_sdiv : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** [build_fdiv x y name b] creates a [%name = fdiv %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateFDiv]. *) -external build_fdiv : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_fdiv" +val build_fdiv : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** [build_urem x y name b] creates a [%name = urem %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateURem]. *) -external build_urem : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_urem" +val build_urem : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** [build_SRem x y name b] creates a [%name = srem %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateSRem]. *) -external build_srem : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_srem" +val build_srem : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** [build_frem x y name b] creates a [%name = frem %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateFRem]. *) -external build_frem : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_frem" +val build_frem : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** [build_shl x y name b] creates a [%name = shl %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateShl]. *) -external build_shl : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_shl" +val build_shl : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** [build_lshr x y name b] creates a [%name = lshr %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateLShr]. *) -external build_lshr : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_lshr" +val build_lshr : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** [build_ashr x y name b] creates a [%name = ashr %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateAShr]. *) -external build_ashr : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_ashr" +val build_ashr : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** [build_and x y name b] creates a [%name = and %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateAnd]. *) -external build_and : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_and" +val build_and : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** [build_or x y name b] creates a [%name = or %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateOr]. *) -external build_or : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_or" +val build_or : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** [build_xor x y name b] creates a [%name = xor %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateXor]. *) -external build_xor : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_xor" +val build_xor : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** [build_neg x name b] creates a [%name = sub 0, %x] instruction at the position specified by the instruction builder [b]. [-0.0] is used for floating point types to compute the correct sign. See the method [llvm::LLVMBuilder::CreateNeg]. *) -external build_neg : llvalue -> string -> llbuilder -> llvalue - = "llvm_build_neg" +val build_neg : llvalue -> string -> llbuilder -> llvalue + (** [build_nsw_neg x name b] creates a [%name = nsw sub 0, %x] instruction at the position specified by the instruction builder [b]. [-0.0] is used for floating point types to compute the correct sign. See the method [llvm::LLVMBuilder::CreateNeg]. *) -external build_nsw_neg : llvalue -> string -> llbuilder -> llvalue - = "llvm_build_nsw_neg" +val build_nsw_neg : llvalue -> string -> llbuilder -> llvalue + (** [build_nuw_neg x name b] creates a [%name = nuw sub 0, %x] instruction at the position specified by the instruction builder [b]. [-0.0] is used for floating point types to compute the correct sign. See the method [llvm::LLVMBuilder::CreateNeg]. *) -external build_nuw_neg : llvalue -> string -> llbuilder -> llvalue - = "llvm_build_nuw_neg" +val build_nuw_neg : llvalue -> string -> llbuilder -> llvalue + (** [build_fneg x name b] creates a [%name = fsub 0, %x] instruction at the position specified by the instruction builder [b]. [-0.0] is used for floating point types to compute the correct sign. See the method [llvm::LLVMBuilder::CreateFNeg]. *) -external build_fneg : llvalue -> string -> llbuilder -> llvalue - = "llvm_build_fneg" +val build_fneg : llvalue -> string -> llbuilder -> llvalue + (** [build_xor x name b] creates a [%name = xor %x, -1] instruction at the position specified by the instruction builder [b]. [-1] is the correct "all ones" value for the type of [x]. See the method [llvm::LLVMBuilder::CreateXor]. *) -external build_not : llvalue -> string -> llbuilder -> llvalue - = "llvm_build_not" +val build_not : llvalue -> string -> llbuilder -> llvalue + (** {7 Memory} *) @@ -1901,63 +1901,63 @@ [%name = alloca %ty] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateAlloca]. *) -external build_alloca : lltype -> string -> llbuilder -> llvalue - = "llvm_build_alloca" +val build_alloca : lltype -> string -> llbuilder -> llvalue + (** [build_array_alloca ty n name b] creates a [%name = alloca %ty, %n] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateAlloca]. *) -external build_array_alloca : lltype -> llvalue -> string -> llbuilder -> - llvalue = "llvm_build_array_alloca" +val build_array_alloca : lltype -> llvalue -> string -> llbuilder -> + llvalue (** [build_load v name b] creates a [%name = load %v] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateLoad]. *) -external build_load : llvalue -> string -> llbuilder -> llvalue - = "llvm_build_load" +val build_load : llvalue -> string -> llbuilder -> llvalue + (** [build_store v p b] creates a [store %v, %p] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateStore]. *) -external build_store : llvalue -> llvalue -> llbuilder -> llvalue - = "llvm_build_store" +val build_store : llvalue -> llvalue -> llbuilder -> llvalue + (** [build_gep p indices name b] creates a [%name = getelementptr %p, indices...] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateGetElementPtr]. *) -external build_gep : llvalue -> llvalue array -> string -> llbuilder -> llvalue - = "llvm_build_gep" +val build_gep : llvalue -> llvalue array -> string -> llbuilder -> llvalue + (** [build_in_bounds_gep p indices name b] creates a [%name = gelementptr inbounds %p, indices...] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateInBoundsGetElementPtr]. *) -external build_in_bounds_gep : llvalue -> llvalue array -> string -> llbuilder -> - llvalue = "llvm_build_in_bounds_gep" +val build_in_bounds_gep : llvalue -> llvalue array -> string -> llbuilder -> + llvalue (** [build_struct_gep p idx name b] creates a [%name = getelementptr %p, 0, idx] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateStructGetElementPtr]. *) -external build_struct_gep : llvalue -> int -> string -> llbuilder -> - llvalue = "llvm_build_struct_gep" +val build_struct_gep : llvalue -> int -> string -> llbuilder -> + llvalue (** [build_global_string str name b] creates a series of instructions that adds a global string at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateGlobalString]. *) -external build_global_string : string -> string -> llbuilder -> llvalue - = "llvm_build_global_string" +val build_global_string : string -> string -> llbuilder -> llvalue + (** [build_global_stringptr str name b] creates a series of instructions that adds a global string pointer at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateGlobalStringPtr]. *) -external build_global_stringptr : string -> string -> llbuilder -> llvalue - = "llvm_build_global_stringptr" +val build_global_stringptr : string -> string -> llbuilder -> llvalue + (** {7 Casts} *) @@ -1966,121 +1966,121 @@ [%name = trunc %p to %ty] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateTrunc]. *) -external build_trunc : llvalue -> lltype -> string -> llbuilder -> llvalue - = "llvm_build_trunc" +val build_trunc : llvalue -> lltype -> string -> llbuilder -> llvalue + (** [build_zext v ty name b] creates a [%name = zext %p to %ty] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateZExt]. *) -external build_zext : llvalue -> lltype -> string -> llbuilder -> llvalue - = "llvm_build_zext" +val build_zext : llvalue -> lltype -> string -> llbuilder -> llvalue + (** [build_sext v ty name b] creates a [%name = sext %p to %ty] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateSExt]. *) -external build_sext : llvalue -> lltype -> string -> llbuilder -> llvalue - = "llvm_build_sext" +val build_sext : llvalue -> lltype -> string -> llbuilder -> llvalue + (** [build_fptoui v ty name b] creates a [%name = fptoui %p to %ty] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateFPToUI]. *) -external build_fptoui : llvalue -> lltype -> string -> llbuilder -> llvalue - = "llvm_build_fptoui" +val build_fptoui : llvalue -> lltype -> string -> llbuilder -> llvalue + (** [build_fptosi v ty name b] creates a [%name = fptosi %p to %ty] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateFPToSI]. *) -external build_fptosi : llvalue -> lltype -> string -> llbuilder -> llvalue - = "llvm_build_fptosi" +val build_fptosi : llvalue -> lltype -> string -> llbuilder -> llvalue + (** [build_uitofp v ty name b] creates a [%name = uitofp %p to %ty] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateUIToFP]. *) -external build_uitofp : llvalue -> lltype -> string -> llbuilder -> llvalue - = "llvm_build_uitofp" +val build_uitofp : llvalue -> lltype -> string -> llbuilder -> llvalue + (** [build_sitofp v ty name b] creates a [%name = sitofp %p to %ty] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateSIToFP]. *) -external build_sitofp : llvalue -> lltype -> string -> llbuilder -> llvalue - = "llvm_build_sitofp" +val build_sitofp : llvalue -> lltype -> string -> llbuilder -> llvalue + (** [build_fptrunc v ty name b] creates a [%name = fptrunc %p to %ty] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateFPTrunc]. *) -external build_fptrunc : llvalue -> lltype -> string -> llbuilder -> llvalue - = "llvm_build_fptrunc" +val build_fptrunc : llvalue -> lltype -> string -> llbuilder -> llvalue + (** [build_fpext v ty name b] creates a [%name = fpext %p to %ty] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateFPExt]. *) -external build_fpext : llvalue -> lltype -> string -> llbuilder -> llvalue - = "llvm_build_fpext" +val build_fpext : llvalue -> lltype -> string -> llbuilder -> llvalue + (** [build_ptrtoint v ty name b] creates a [%name = prtotint %p to %ty] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreatePtrToInt]. *) -external build_ptrtoint : llvalue -> lltype -> string -> llbuilder -> llvalue - = "llvm_build_prttoint" +val build_ptrtoint : llvalue -> lltype -> string -> llbuilder -> llvalue + (** [build_inttoptr v ty name b] creates a [%name = inttoptr %p to %ty] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateIntToPtr]. *) -external build_inttoptr : llvalue -> lltype -> string -> llbuilder -> llvalue - = "llvm_build_inttoptr" +val build_inttoptr : llvalue -> lltype -> string -> llbuilder -> llvalue + (** [build_bitcast v ty name b] creates a [%name = bitcast %p to %ty] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateBitCast]. *) -external build_bitcast : llvalue -> lltype -> string -> llbuilder -> llvalue - = "llvm_build_bitcast" +val build_bitcast : llvalue -> lltype -> string -> llbuilder -> llvalue + (** [build_zext_or_bitcast v ty name b] creates a zext or bitcast instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateZExtOrBitCast]. *) -external build_zext_or_bitcast : llvalue -> lltype -> string -> llbuilder -> - llvalue = "llvm_build_zext_or_bitcast" +val build_zext_or_bitcast : llvalue -> lltype -> string -> llbuilder -> + llvalue (** [build_sext_or_bitcast v ty name b] creates a sext or bitcast instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateSExtOrBitCast]. *) -external build_sext_or_bitcast : llvalue -> lltype -> string -> llbuilder -> - llvalue = "llvm_build_sext_or_bitcast" +val build_sext_or_bitcast : llvalue -> lltype -> string -> llbuilder -> + llvalue (** [build_trunc_or_bitcast v ty name b] creates a trunc or bitcast instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateZExtOrBitCast]. *) -external build_trunc_or_bitcast : llvalue -> lltype -> string -> llbuilder -> - llvalue = "llvm_build_trunc_or_bitcast" +val build_trunc_or_bitcast : llvalue -> lltype -> string -> llbuilder -> + llvalue (** [build_pointercast v ty name b] creates a bitcast or pointer-to-int instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreatePointerCast]. *) -external build_pointercast : llvalue -> lltype -> string -> llbuilder -> llvalue - = "llvm_build_pointercast" +val build_pointercast : llvalue -> lltype -> string -> llbuilder -> llvalue + (** [build_intcast v ty name b] creates a zext, bitcast, or trunc instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateIntCast]. *) -external build_intcast : llvalue -> lltype -> string -> llbuilder -> llvalue - = "llvm_build_intcast" +val build_intcast : llvalue -> lltype -> string -> llbuilder -> llvalue + (** [build_fpcast v ty name b] creates a fpext, bitcast, or fptrunc instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateFPCast]. *) -external build_fpcast : llvalue -> lltype -> string -> llbuilder -> llvalue - = "llvm_build_fpcast" +val build_fpcast : llvalue -> lltype -> string -> llbuilder -> llvalue + (** {7 Comparisons} *) @@ -2089,15 +2089,15 @@ [%name = icmp %pred %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateICmp]. *) -external build_icmp : Icmp.t -> llvalue -> llvalue -> string -> - llbuilder -> llvalue = "llvm_build_icmp" +val build_icmp : Icmp.t -> llvalue -> llvalue -> string -> + llbuilder -> llvalue (** [build_fcmp pred x y name b] creates a [%name = fcmp %pred %x, %y] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateFCmp]. *) -external build_fcmp : Fcmp.t -> llvalue -> llvalue -> string -> - llbuilder -> llvalue = "llvm_build_fcmp" +val build_fcmp : Fcmp.t -> llvalue -> llvalue -> string -> + llbuilder -> llvalue (** {7 Miscellaneous instructions} *) @@ -2107,85 +2107,85 @@ instruction at the position specified by the instruction builder [b]. [incoming] is a list of [(llvalue, llbasicblock)] tuples. See the method [llvm::LLVMBuilder::CreatePHI]. *) -external build_phi : (llvalue * llbasicblock) list -> string -> llbuilder -> - llvalue = "llvm_build_phi" +val build_phi : (llvalue * llbasicblock) list -> string -> llbuilder -> + llvalue (** [build_call fn args name b] creates a [%name = call %fn(args...)] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateCall]. *) -external build_call : llvalue -> llvalue array -> string -> llbuilder -> llvalue - = "llvm_build_call" +val build_call : llvalue -> llvalue array -> string -> llbuilder -> llvalue + (** [build_select cond thenv elsev name b] creates a [%name = select %cond, %thenv, %elsev] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateSelect]. *) -external build_select : llvalue -> llvalue -> llvalue -> string -> llbuilder -> - llvalue = "llvm_build_select" +val build_select : llvalue -> llvalue -> llvalue -> string -> llbuilder -> + llvalue (** [build_va_arg valist argty name b] creates a [%name = va_arg %valist, %argty] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateVAArg]. *) -external build_va_arg : llvalue -> lltype -> string -> llbuilder -> llvalue - = "llvm_build_va_arg" +val build_va_arg : llvalue -> lltype -> string -> llbuilder -> llvalue + (** [build_extractelement vec i name b] creates a [%name = extractelement %vec, %i] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateExtractElement]. *) -external build_extractelement : llvalue -> llvalue -> string -> llbuilder -> - llvalue = "llvm_build_extractelement" +val build_extractelement : llvalue -> llvalue -> string -> llbuilder -> + llvalue (** [build_insertelement vec elt i name b] creates a [%name = insertelement %vec, %elt, %i] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateInsertElement]. *) -external build_insertelement : llvalue -> llvalue -> llvalue -> string -> - llbuilder -> llvalue = "llvm_build_insertelement" +val build_insertelement : llvalue -> llvalue -> llvalue -> string -> + llbuilder -> llvalue (** [build_shufflevector veca vecb mask name b] creates a [%name = shufflevector %veca, %vecb, %mask] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateShuffleVector]. *) -external build_shufflevector : llvalue -> llvalue -> llvalue -> string -> - llbuilder -> llvalue = "llvm_build_shufflevector" +val build_shufflevector : llvalue -> llvalue -> llvalue -> string -> + llbuilder -> llvalue (** [build_insertvalue agg idx name b] creates a [%name = extractvalue %agg, %idx] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateExtractValue]. *) -external build_extractvalue : llvalue -> int -> string -> llbuilder -> llvalue - = "llvm_build_extractvalue" +val build_extractvalue : llvalue -> int -> string -> llbuilder -> llvalue + (** [build_insertvalue agg val idx name b] creates a [%name = insertvalue %agg, %val, %idx] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateInsertValue]. *) -external build_insertvalue : llvalue -> llvalue -> int -> string -> llbuilder -> - llvalue = "llvm_build_insertvalue" +val build_insertvalue : llvalue -> llvalue -> int -> string -> llbuilder -> + llvalue (** [build_is_null val name b] creates a [%name = icmp eq %val, null] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateIsNull]. *) -external build_is_null : llvalue -> string -> llbuilder -> llvalue - = "llvm_build_is_null" +val build_is_null : llvalue -> string -> llbuilder -> llvalue + (** [build_is_not_null val name b] creates a [%name = icmp ne %val, null] instruction at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreateIsNotNull]. *) -external build_is_not_null : llvalue -> string -> llbuilder -> llvalue - = "llvm_build_is_not_null" +val build_is_not_null : llvalue -> string -> llbuilder -> llvalue + (** [build_ptrdiff lhs rhs name b] creates a series of instructions that measure the difference between two pointer values at the position specified by the instruction builder [b]. See the method [llvm::LLVMBuilder::CreatePtrDiff]. *) -external build_ptrdiff : llvalue -> llvalue -> string -> llbuilder -> llvalue - = "llvm_build_ptrdiff" +val build_ptrdiff : llvalue -> llvalue -> string -> llbuilder -> llvalue + (** {6 Memory buffers} *) @@ -2194,14 +2194,14 @@ (** [of_file p] is the memory buffer containing the contents of the file at path [p]. If the file could not be read, then [IoError msg] is raised. *) - external of_file : string -> llmemorybuffer = "llvm_memorybuffer_of_file" + val of_file : string -> llmemorybuffer (** [stdin ()] is the memory buffer containing the contents of standard input. If standard input is empty, then [IoError msg] is raised. *) - external of_stdin : unit -> llmemorybuffer = "llvm_memorybuffer_of_stdin" + val of_stdin : unit -> llmemorybuffer (** Disposes of a memory buffer. *) - external dispose : llmemorybuffer -> unit = "llvm_memorybuffer_dispose" + val dispose : llmemorybuffer -> unit end @@ -2216,44 +2216,44 @@ type of pipeline is suitable for link-time optimization and whole-module transformations. See the constructor of [llvm::PassManager]. *) - external create : unit -> [ `Module ] t = "llvm_passmanager_create" + val create : unit -> [ `Module ] t (** [PassManager.create_function m] constructs a new function-by-function pass pipeline over the module [m]. It does not take ownership of [m]. This type of pipeline is suitable for code generation and JIT compilation tasks. See the constructor of [llvm::FunctionPassManager]. *) - external create_function : llmodule -> [ `Function ] t - = "LLVMCreateFunctionPassManager" + val create_function : llmodule -> [ `Function ] t + (** [run_module m pm] initializes, executes on the module [m], and finalizes all of the passes scheduled in the pass manager [pm]. Returns [true] if any of the passes modified the module, [false] otherwise. See the [llvm::PassManager::run] method. *) - external run_module : llmodule -> [ `Module ] t -> bool - = "llvm_passmanager_run_module" + val run_module : llmodule -> [ `Module ] t -> bool + (** [initialize fpm] initializes all of the function passes scheduled in the function pass manager [fpm]. Returns [true] if any of the passes modified the module, [false] otherwise. See the [llvm::FunctionPassManager::doInitialization] method. *) - external initialize : [ `Function ] t -> bool = "llvm_passmanager_initialize" + val initialize : [ `Function ] t -> bool (** [run_function f fpm] executes all of the function passes scheduled in the function pass manager [fpm] over the function [f]. Returns [true] if any of the passes modified [f], [false] otherwise. See the [llvm::FunctionPassManager::run] method. *) - external run_function : llvalue -> [ `Function ] t -> bool - = "llvm_passmanager_run_function" + val run_function : llvalue -> [ `Function ] t -> bool + (** [finalize fpm] finalizes all of the function passes scheduled in in the function pass manager [fpm]. Returns [true] if any of the passes modified the module, [false] otherwise. See the [llvm::FunctionPassManager::doFinalization] method. *) - external finalize : [ `Function ] t -> bool = "llvm_passmanager_finalize" + val finalize : [ `Function ] t -> bool (** Frees the memory of a pass pipeline. For function pipelines, does not free the module. See the destructor of [llvm::BasePassManager]. *) - external dispose : [< any ] t -> unit = "llvm_passmanager_dispose" + val dispose : [< any ] t -> unit end Added: llvm/trunk/test/Bindings/Ocaml/ext_exc.ml URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bindings/Ocaml/ext_exc.ml?rev=122497&view=auto ============================================================================== --- llvm/trunk/test/Bindings/Ocaml/ext_exc.ml (added) +++ llvm/trunk/test/Bindings/Ocaml/ext_exc.ml Thu Dec 23 09:49:26 2010 @@ -0,0 +1,16 @@ +(* RUN: %ocamlopt -warn-error A llvm.cmxa llvm_bitreader.cmxa llvm_executionengine.cmxa %s -o %t + * RUN: %t ();; +let _ = + try + ignore (Llvm.MemoryBuffer.of_file "/path/to/nonexistent/file") + with + Llvm.IoError _ -> ();; From sabre at nondot.org Thu Dec 23 11:03:20 2010 From: sabre at nondot.org (Chris Lattner) Date: Thu, 23 Dec 2010 17:03:20 -0000 Subject: [llvm-commits] [llvm] r122506 - in /llvm/trunk/utils/TableGen: DAGISelMatcher.cpp DAGISelMatcher.h DAGISelMatcherEmitter.cpp DAGISelMatcherGen.cpp DAGISelMatcherOpt.cpp Message-ID: <20101223170320.434772A6C12C@llvm.org> Author: lattner Date: Thu Dec 23 11:03:20 2010 New Revision: 122506 URL: http://llvm.org/viewvc/llvm-project?rev=122506&view=rev Log: continue renaming flag -> glue. Modified: llvm/trunk/utils/TableGen/DAGISelMatcher.cpp llvm/trunk/utils/TableGen/DAGISelMatcher.h llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp llvm/trunk/utils/TableGen/DAGISelMatcherOpt.cpp Modified: llvm/trunk/utils/TableGen/DAGISelMatcher.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcher.cpp?rev=122506&r1=122505&r2=122506&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/DAGISelMatcher.cpp (original) +++ llvm/trunk/utils/TableGen/DAGISelMatcher.cpp Thu Dec 23 11:03:20 2010 @@ -107,8 +107,8 @@ OS.indent(indent) << "RecordMemRef\n"; } -void CaptureFlagInputMatcher::printImpl(raw_ostream &OS, unsigned indent) const{ - OS.indent(indent) << "CaptureFlagInput\n"; +void CaptureGlueInputMatcher::printImpl(raw_ostream &OS, unsigned indent) const{ + OS.indent(indent) << "CaptureGlueInput\n"; } void MoveChildMatcher::printImpl(raw_ostream &OS, unsigned indent) const { @@ -246,8 +246,8 @@ OS << ")\n"; } -void MarkFlagResultsMatcher::printImpl(raw_ostream &OS, unsigned indent) const { - OS.indent(indent) << "MarkFlagResults \n"; +void MarkGlueResultsMatcher::printImpl(raw_ostream &OS, unsigned indent) const { + OS.indent(indent) << "MarkGlueResults \n"; } void CompleteMatchMatcher::printImpl(raw_ostream &OS, unsigned indent) const { @@ -316,8 +316,8 @@ } -unsigned MarkFlagResultsMatcher::getHashImpl() const { - return HashUnsigneds(FlagResultNodes.begin(), FlagResultNodes.end()); +unsigned MarkGlueResultsMatcher::getHashImpl() const { + return HashUnsigneds(GlueResultNodes.begin(), GlueResultNodes.end()); } unsigned CompleteMatchMatcher::getHashImpl() const { Modified: llvm/trunk/utils/TableGen/DAGISelMatcher.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcher.h?rev=122506&r1=122505&r2=122506&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/DAGISelMatcher.h (original) +++ llvm/trunk/utils/TableGen/DAGISelMatcher.h Thu Dec 23 11:03:20 2010 @@ -45,7 +45,7 @@ RecordNode, // Record the current node. RecordChild, // Record a child of the current node. RecordMemRef, // Record the memref in the current node. - CaptureFlagInput, // If the current node has an input flag, save it. + CaptureGlueInput, // If the current node has an input glue, save it. MoveChild, // Move current node to specified child. MoveParent, // Move current node to parent. @@ -75,7 +75,7 @@ EmitCopyToReg, // Emit a copytoreg into a physreg. EmitNode, // Create a DAG node EmitNodeXForm, // Run a SDNodeXForm - MarkFlagResults, // Indicate which interior nodes have flag results. + MarkGlueResults, // Indicate which interior nodes have glue results. CompleteMatch, // Finish a match and update the results. MorphNodeTo // Build a node, finish a match and update results. }; @@ -306,14 +306,14 @@ }; -/// CaptureFlagInputMatcher - If the current record has a flag input, record +/// CaptureGlueInputMatcher - If the current record has a glue input, record /// it so that it is used as an input to the generated code. -class CaptureFlagInputMatcher : public Matcher { +class CaptureGlueInputMatcher : public Matcher { public: - CaptureFlagInputMatcher() : Matcher(CaptureFlagInput) {} + CaptureGlueInputMatcher() : Matcher(CaptureGlueInput) {} static inline bool classof(const Matcher *N) { - return N->getKind() == CaptureFlagInput; + return N->getKind() == CaptureGlueInput; } virtual bool isSafeToReorderWithPatternPredicate() const { return true; } @@ -893,7 +893,7 @@ }; /// EmitCopyToRegMatcher - Emit a CopyToReg node from a value to a physreg, -/// pushing the chain and flag results. +/// pushing the chain and glue results. /// class EmitCopyToRegMatcher : public Matcher { unsigned SrcSlot; // Value to copy into the physreg. @@ -965,12 +965,12 @@ EmitNodeMatcherCommon(const std::string &opcodeName, const MVT::SimpleValueType *vts, unsigned numvts, const unsigned *operands, unsigned numops, - bool hasChain, bool hasInFlag, bool hasOutFlag, + bool hasChain, bool hasInGlue, bool hasOutGlue, bool hasmemrefs, int numfixedarityoperands, bool isMorphNodeTo) : Matcher(isMorphNodeTo ? MorphNodeTo : EmitNode), OpcodeName(opcodeName), VTs(vts, vts+numvts), Operands(operands, operands+numops), - HasChain(hasChain), HasInFlag(hasInFlag), HasOutFlag(hasOutFlag), + HasChain(hasChain), HasInFlag(hasInGlue), HasOutFlag(hasOutGlue), HasMemRefs(hasmemrefs), NumFixedArityOperands(numfixedarityoperands) {} const std::string &getOpcodeName() const { return OpcodeName; } @@ -1052,30 +1052,30 @@ } }; -/// 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. -class MarkFlagResultsMatcher : public Matcher { - SmallVector FlagResultNodes; +/// MarkGlueResultsMatcher - This node indicates which non-root nodes in the +/// pattern produce glue. This allows CompleteMatchMatcher to update them +/// with the output glue of the resultant code. +class MarkGlueResultsMatcher : public Matcher { + SmallVector GlueResultNodes; public: - MarkFlagResultsMatcher(const unsigned *nodes, unsigned NumNodes) - : Matcher(MarkFlagResults), FlagResultNodes(nodes, nodes+NumNodes) {} + MarkGlueResultsMatcher(const unsigned *nodes, unsigned NumNodes) + : Matcher(MarkGlueResults), GlueResultNodes(nodes, nodes+NumNodes) {} - unsigned getNumNodes() const { return FlagResultNodes.size(); } + unsigned getNumNodes() const { return GlueResultNodes.size(); } unsigned getNode(unsigned i) const { - assert(i < FlagResultNodes.size()); - return FlagResultNodes[i]; + assert(i < GlueResultNodes.size()); + return GlueResultNodes[i]; } static inline bool classof(const Matcher *N) { - return N->getKind() == MarkFlagResults; + return N->getKind() == MarkGlueResults; } private: virtual void printImpl(raw_ostream &OS, unsigned indent) const; virtual bool isEqualImpl(const Matcher *M) const { - return cast(M)->FlagResultNodes == FlagResultNodes; + return cast(M)->GlueResultNodes == GlueResultNodes; } virtual unsigned getHashImpl() const; }; Modified: llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp?rev=122506&r1=122505&r2=122506&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp Thu Dec 23 11:03:20 2010 @@ -220,7 +220,7 @@ OS << "OPC_RecordMemRef,\n"; return 1; - case Matcher::CaptureFlagInput: + case Matcher::CaptureGlueInput: OS << "OPC_CaptureFlagInput,\n"; return 1; @@ -531,8 +531,8 @@ return 6+EN->getNumVTs()+NumOperandBytes; } - case Matcher::MarkFlagResults: { - const MarkFlagResultsMatcher *CFR = cast(N); + case Matcher::MarkGlueResults: { + const MarkGlueResultsMatcher *CFR = cast(N); OS << "OPC_MarkFlagResults, " << CFR->getNumNodes() << ", "; unsigned NumOperandBytes = 0; for (unsigned i = 0, e = CFR->getNumNodes(); i != e; ++i) @@ -742,7 +742,7 @@ case Matcher::RecordNode: OS << "OPC_RecordNode"; break; case Matcher::RecordChild: OS << "OPC_RecordChild"; break; case Matcher::RecordMemRef: OS << "OPC_RecordMemRef"; break; - case Matcher::CaptureFlagInput: OS << "OPC_CaptureFlagInput"; break; + case Matcher::CaptureGlueInput: OS << "OPC_CaptureFlagInput"; break; case Matcher::MoveChild: OS << "OPC_MoveChild"; break; case Matcher::MoveParent: OS << "OPC_MoveParent"; break; case Matcher::CheckSame: OS << "OPC_CheckSame"; break; @@ -771,7 +771,7 @@ case Matcher::EmitNode: OS << "OPC_EmitNode"; break; case Matcher::MorphNodeTo: OS << "OPC_MorphNodeTo"; break; case Matcher::EmitNodeXForm: OS << "OPC_EmitNodeXForm"; break; - case Matcher::MarkFlagResults: OS << "OPC_MarkFlagResults"; break; + case Matcher::MarkGlueResults: OS << "OPC_MarkFlagResults"; break; case Matcher::CompleteMatch: OS << "OPC_CompleteMatch"; break; } Modified: llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp?rev=122506&r1=122505&r2=122506&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp (original) +++ llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp Thu Dec 23 11:03:20 2010 @@ -68,9 +68,9 @@ /// array of all of the recorded input nodes that have chains. SmallVector MatchedChainNodes; - /// MatchedFlagResultNodes - This maintains the position in the recorded - /// nodes array of all of the recorded input nodes that have flag results. - SmallVector MatchedFlagResultNodes; + /// MatchedGlueResultNodes - This maintains the position in the recorded + /// nodes array of all of the recorded input nodes that have glue results. + SmallVector MatchedGlueResultNodes; /// MatchedComplexPatterns - This maintains a list of all of the /// ComplexPatterns that we need to check. The patterns are known to have @@ -356,7 +356,7 @@ // 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 - // flag). + // glue). if (!NeedCheck) { const SDNodeInfo &PInfo = CGP.getSDNodeInfo(Root->getOperator()); NeedCheck = @@ -374,24 +374,24 @@ } } - // If this node has an output flag and isn't the root, remember it. + // If this node has an output glue and isn't the root, remember it. if (N->NodeHasProperty(SDNPOutFlag, CGP) && N != Pattern.getSrcPattern()) { - // TODO: This redundantly records nodes with both flags and chains. + // TODO: This redundantly records nodes with both glues and chains. // Record the node and remember it in our chained nodes list. AddMatcher(new RecordMatcher("'" + N->getOperator()->getName() + - "' flag output node", + "' glue output node", NextRecordedOperandNo)); - // Remember all of the nodes with output flags our pattern will match. - MatchedFlagResultNodes.push_back(NextRecordedOperandNo++); + // Remember all of the nodes with output glue our pattern will match. + MatchedGlueResultNodes.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 this node is known to have an input glue or if it *might* have an input + // glue, capture it as the glue input of the pattern. if (N->NodeHasProperty(SDNPOptInFlag, CGP) || N->NodeHasProperty(SDNPInFlag, CGP)) - AddMatcher(new CaptureFlagInputMatcher()); + AddMatcher(new CaptureGlueInputMatcher()); for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) { // Get the code suitable for matching this child. Move to the child, check @@ -514,7 +514,7 @@ MatchedChainNodes.push_back(NextRecordedOperandNo-1); } - // TODO: Complex patterns can't have output flags, if they did, we'd want + // TODO: Complex patterns can't have output glues, if they did, we'd want // to record them. } @@ -655,16 +655,16 @@ bool isRoot = N == Pattern.getDstPattern(); - // TreeHasOutFlag - True if this tree has a flag. - bool TreeHasInFlag = false, TreeHasOutFlag = false; + // TreeHasOutGlue - True if this tree has glue. + bool TreeHasInGlue = false, TreeHasOutGlue = false; if (isRoot) { const TreePatternNode *SrcPat = Pattern.getSrcPattern(); - TreeHasInFlag = SrcPat->TreeHasProperty(SDNPOptInFlag, CGP) || + TreeHasInGlue = 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); + TreeHasOutGlue = SrcPat->TreeHasProperty(SDNPOutFlag, CGP); } // NumResults - This is the number of results produced by the instruction in @@ -711,8 +711,8 @@ ++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 + // If this node has input glue or explicitly specified input physregs, we + // need to add chained and glued copyfromreg nodes and materialize the glue // input. if (isRoot && !PhysRegInputs.empty()) { // Emit all of the CopyToReg nodes for the input physical registers. These @@ -720,12 +720,12 @@ for (unsigned i = 0, e = PhysRegInputs.size(); i != e; ++i) AddMatcher(new EmitCopyToRegMatcher(PhysRegInputs[i].second, PhysRegInputs[i].first)); - // Even if the node has no other flag inputs, the resultant node must be - // flagged to the CopyFromReg nodes we just generated. - TreeHasInFlag = true; + // Even if the node has no other glue inputs, the resultant node must be + // glued to the CopyFromReg nodes we just generated. + TreeHasInGlue = true; } - // Result order: node results, chain, flags + // Result order: node results, chain, glue // Determine the result types. SmallVector ResultVTs; @@ -775,17 +775,17 @@ bool NodeHasMemRefs = isRoot && Pattern.getSrcPattern()->TreeHasProperty(SDNPMemOperand, CGP); - assert((!ResultVTs.empty() || TreeHasOutFlag || NodeHasChain) && + assert((!ResultVTs.empty() || TreeHasOutGlue || NodeHasChain) && "Node has no result"); AddMatcher(new EmitNodeMatcher(II.Namespace+"::"+II.TheDef->getName(), ResultVTs.data(), ResultVTs.size(), InstOps.data(), InstOps.size(), - NodeHasChain, TreeHasInFlag, TreeHasOutFlag, + NodeHasChain, TreeHasInGlue, TreeHasOutGlue, NodeHasMemRefs, NumFixedArityOperands, NextRecordedOperandNo)); - // The non-chain and non-flag results of the newly emitted node get recorded. + // The non-chain and non-glue 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; OutputOps.push_back(NextRecordedOperandNo++); @@ -846,7 +846,7 @@ // At this point, we have however many values the result pattern produces. // However, the input pattern might not need all of these. If there are // excess values at the end (such as implicit defs of condition codes etc) - // just lop them off. This doesn't need to worry about flags or chains, just + // just lop them off. This doesn't need to worry about glue or chains, just // explicit results. // unsigned NumSrcResults = Pattern.getSrcPattern()->getNumTypes(); @@ -875,11 +875,11 @@ assert(Ops.size() >= NumSrcResults && "Didn't provide enough results"); Ops.resize(NumSrcResults); - // If the matched pattern covers nodes which define a flag result, emit a node + // If the matched pattern covers nodes which define a glue result, emit a node // that tells the matcher about them so that it can update their results. - if (!MatchedFlagResultNodes.empty()) - AddMatcher(new MarkFlagResultsMatcher(MatchedFlagResultNodes.data(), - MatchedFlagResultNodes.size())); + if (!MatchedGlueResultNodes.empty()) + AddMatcher(new MarkGlueResultsMatcher(MatchedGlueResultNodes.data(), + MatchedGlueResultNodes.size())); AddMatcher(new CompleteMatchMatcher(Ops.data(), Ops.size(), Pattern)); } Modified: llvm/trunk/utils/TableGen/DAGISelMatcherOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcherOpt.cpp?rev=122506&r1=122505&r2=122506&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/DAGISelMatcherOpt.cpp (original) +++ llvm/trunk/utils/TableGen/DAGISelMatcherOpt.cpp Thu Dec 23 11:03:20 2010 @@ -75,7 +75,7 @@ // MarkFlagResults->EmitNode->CompleteMatch when we can to encourage // MorphNodeTo formation. This is safe because MarkFlagResults never refers // to the root of the pattern. - if (isa(N) && isa(N->getNext()) && + if (isa(N) && isa(N->getNext()) && isa(N->getNext()->getNext())) { // Unlink the two nodes from the list. Matcher *EmitNode = MatcherPtr.take(); @@ -100,7 +100,7 @@ if (CM->getResult(i) != RootResultFirst+i) ResultsMatch = false; - // If the selected node defines a subset of the flag/chain results, we + // If the selected node defines a subset of the glue/chain results, we // can't use MorphNodeTo. For example, we can't use MorphNodeTo if the // matched pattern has a chain but the root node doesn't. const PatternToMatch &Pattern = CM->getPattern(); @@ -109,10 +109,10 @@ Pattern.getSrcPattern()->NodeHasProperty(SDNPHasChain, CGP)) ResultsMatch = false; - // If the matched node has a flag and the output root doesn't, we can't + // If the matched node has glue and the output root doesn't, we can't // use MorphNodeTo. // - // NOTE: Strictly speaking, we don't have to check for the flag here + // NOTE: Strictly speaking, we don't have to check for glue here // because the code in the pattern generator doesn't handle it right. We // do it anyway for thoroughness. if (!EN->hasOutFlag() && @@ -121,11 +121,11 @@ // If the root result node defines more results than the source root node - // *and* has a chain or flag input, then we can't match it because it - // would end up replacing the extra result with the chain/flag. + // *and* has a chain or glue input, then we can't match it because it + // would end up replacing the extra result with the chain/glue. #if 0 - if ((EN->hasFlag() || EN->hasChain()) && - EN->getNumNonChainFlagVTs() > ... need to get no results reliably ...) + if ((EN->hasGlue() || EN->hasChain()) && + EN->getNumNonChainGlueVTs() > ... need to get no results reliably ...) ResultMatch = false; #endif From sabre at nondot.org Thu Dec 23 11:13:18 2010 From: sabre at nondot.org (Chris Lattner) Date: Thu, 23 Dec 2010 17:13:18 -0000 Subject: [llvm-commits] [llvm] r122507 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAGISel.h lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp utils/TableGen/DAGISelMatcherEmitter.cpp Message-ID: <20101223171318.5E0962A6C12C@llvm.org> Author: lattner Date: Thu Dec 23 11:13:18 2010 New Revision: 122507 URL: http://llvm.org/viewvc/llvm-project?rev=122507&view=rev Log: sdisel flag -> glue. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h?rev=122507&r1=122506&r2=122507&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h Thu Dec 23 11:13:18 2010 @@ -145,10 +145,10 @@ }; enum { - OPFL_None = 0, // Node has no chain or flag input and isn't variadic. + OPFL_None = 0, // Node has no chain or flag input and isn't variadic. OPFL_Chain = 1, // Node has a chain input. - OPFL_FlagInput = 2, // Node has a flag input. - OPFL_FlagOutput = 4, // Node has a flag output. + OPFL_GlueInput = 2, // Node has a glue input. + OPFL_GlueOutput = 4, // Node has a glue output. OPFL_MemRefs = 8, // Node gets accumulated MemRefs. OPFL_Variadic0 = 1<<4, // Node is variadic, root has 0 fixed inputs. OPFL_Variadic1 = 2<<4, // Node is variadic, root has 1 fixed inputs. @@ -305,10 +305,10 @@ /// state machines that start with a OPC_SwitchOpcode node. std::vector OpcodeOffset; - void UpdateChainsAndFlags(SDNode *NodeToMatch, SDValue InputChain, - const SmallVectorImpl &ChainNodesMatched, - SDValue InputFlag,const SmallVectorImpl &F, - bool isMorphNodeTo); + void UpdateChainsAndGlue(SDNode *NodeToMatch, SDValue InputChain, + const SmallVectorImpl &ChainNodesMatched, + SDValue InputGlue, const SmallVectorImpl &F, + bool isMorphNodeTo); }; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=122507&r1=122506&r2=122507&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Dec 23 11:13:18 2010 @@ -1288,7 +1288,7 @@ unsigned i = InlineAsm::Op_FirstOperand, e = InOps.size(); if (InOps[e-1].getValueType() == MVT::Glue) - --e; // Don't process a flag operand if it is here. + --e; // Don't process a glue operand if it is here. while (i != e) { unsigned Flags = cast(InOps[i])->getZExtValue(); @@ -1315,15 +1315,15 @@ } } - // Add the flag input back if present. + // Add the glue input back if present. if (e != InOps.size()) Ops.push_back(InOps.back()); } -/// findFlagUse - Return use of EVT::Flag value produced by the specified +/// findGlueUse - Return use of MVT::Glue value produced by the specified /// SDNode. /// -static SDNode *findFlagUse(SDNode *N) { +static SDNode *findGlueUse(SDNode *N) { unsigned FlagResNo = N->getNumValues()-1; for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) { SDUse &Use = I.getUse(); @@ -1345,7 +1345,7 @@ // never find it. // // The Use may be -1 (unassigned) if it is a newly allocated node. This can - // happen because we scan down to newly selected nodes in the case of flag + // happen because we scan down to newly selected nodes in the case of glue // uses. if ((Use->getNodeId() < Def->getNodeId() && Use->getNodeId() != -1)) return false; @@ -1406,8 +1406,8 @@ // // * indicates nodes to be folded together. // - // If Root produces a flag, then it gets (even more) interesting. Since it - // will be "glued" together with its flag use in the scheduler, we need to + // If Root produces glue, then it gets (even more) interesting. Since it + // will be "glued" together with its glue use in the scheduler, we need to // check if it might reach N. // // [N*] // @@ -1425,24 +1425,24 @@ // ^ / // // f / // // | / // - // [FU] // + // [GU] // // - // If FU (flag use) indirectly reaches N (the load), and Root folds N - // (call it Fold), then X is a predecessor of FU and a successor of - // Fold. But since Fold and FU are flagged together, this will create + // If GU (glue use) indirectly reaches N (the load), and Root folds N + // (call it Fold), then X is a predecessor of GU and a successor of + // Fold. But since Fold and GU are glued together, this will create // a cycle in the scheduling graph. - // If the node has flags, walk down the graph to the "lowest" node in the - // flagged set. + // If the node has glue, walk down the graph to the "lowest" node in the + // glueged set. EVT VT = Root->getValueType(Root->getNumValues()-1); while (VT == MVT::Glue) { - SDNode *FU = findFlagUse(Root); - if (FU == NULL) + SDNode *GU = findGlueUse(Root); + if (GU == NULL) break; - Root = FU; + Root = GU; VT = Root->getValueType(Root->getNumValues()-1); - // If our query node has a flag result with a use, we've walked up it. If + // If our query node has a glue result with a use, we've walked up it. If // the user (which has already been selected) has a chain or indirectly uses // the chain, our WalkChainUsers predicate will not consider it. Because of // this, we cannot ignore chains in this predicate. @@ -1489,20 +1489,20 @@ } -/// UpdateChainsAndFlags - When a match is complete, this method updates uses of -/// interior flag and chain results to use the new flag and chain results. +/// UpdateChainsAndGlue - When a match is complete, this method updates uses of +/// interior glue and chain results to use the new glue and chain results. void SelectionDAGISel:: -UpdateChainsAndFlags(SDNode *NodeToMatch, SDValue InputChain, - const SmallVectorImpl &ChainNodesMatched, - SDValue InputFlag, - const SmallVectorImpl &FlagResultNodesMatched, - bool isMorphNodeTo) { +UpdateChainsAndGlue(SDNode *NodeToMatch, SDValue InputChain, + const SmallVectorImpl &ChainNodesMatched, + SDValue InputGlue, + const SmallVectorImpl &GlueResultNodesMatched, + bool isMorphNodeTo) { SmallVector NowDeadNodes; ISelUpdater ISU(ISelPosition); // Now that all the normal results are replaced, we replace the chain and - // flag results if present. + // glue results if present. if (!ChainNodesMatched.empty()) { assert(InputChain.getNode() != 0 && "Matched input chains but didn't produce a chain"); @@ -1533,21 +1533,21 @@ } } - // If the result produces a flag, update any flag results in the matched - // pattern with the flag result. - if (InputFlag.getNode() != 0) { + // If the result produces glue, update any glue results in the matched + // pattern with the glue result. + if (InputGlue.getNode() != 0) { // Handle any interior nodes explicitly marked. - for (unsigned i = 0, e = FlagResultNodesMatched.size(); i != e; ++i) { - SDNode *FRN = FlagResultNodesMatched[i]; + for (unsigned i = 0, e = GlueResultNodesMatched.size(); i != e; ++i) { + SDNode *FRN = GlueResultNodesMatched[i]; // If this node was already deleted, don't look at it. if (FRN->getOpcode() == ISD::DELETED_NODE) continue; assert(FRN->getValueType(FRN->getNumValues()-1) == MVT::Glue && - "Doesn't have a flag result"); + "Doesn't have a glue result"); CurDAG->ReplaceAllUsesOfValueWith(SDValue(FRN, FRN->getNumValues()-1), - InputFlag, &ISU); + InputGlue, &ISU); // If the node became dead and we haven't already seen it, delete it. if (FRN->use_empty() && @@ -1745,15 +1745,15 @@ const SDValue *Ops, unsigned NumOps, unsigned EmitNodeInfo) { // It is possible we're using MorphNodeTo to replace a node with no // normal results with one that has a normal result (or we could be - // adding a chain) and the input could have flags and chains as well. + // adding a chain) and the input could have glue and chains as well. // In this case we need to shift the operands down. // FIXME: This is a horrible hack and broken in obscure cases, no worse // than the old isel though. - int OldFlagResultNo = -1, OldChainResultNo = -1; + int OldGlueResultNo = -1, OldChainResultNo = -1; unsigned NTMNumResults = Node->getNumValues(); if (Node->getValueType(NTMNumResults-1) == MVT::Glue) { - OldFlagResultNo = NTMNumResults-1; + OldGlueResultNo = NTMNumResults-1; if (NTMNumResults != 1 && Node->getValueType(NTMNumResults-2) == MVT::Other) OldChainResultNo = NTMNumResults-2; @@ -1774,13 +1774,13 @@ } unsigned ResNumResults = Res->getNumValues(); - // Move the flag if needed. - if ((EmitNodeInfo & OPFL_FlagOutput) && OldFlagResultNo != -1 && - (unsigned)OldFlagResultNo != ResNumResults-1) - CurDAG->ReplaceAllUsesOfValueWith(SDValue(Node, OldFlagResultNo), + // Move the glue if needed. + if ((EmitNodeInfo & OPFL_GlueOutput) && OldGlueResultNo != -1 && + (unsigned)OldGlueResultNo != ResNumResults-1) + CurDAG->ReplaceAllUsesOfValueWith(SDValue(Node, OldGlueResultNo), SDValue(Res, ResNumResults-1)); - if ((EmitNodeInfo & OPFL_FlagOutput) != 0) + if ((EmitNodeInfo & OPFL_GlueOutput) != 0) --ResNumResults; // Move the chain reference if needed. @@ -1978,11 +1978,11 @@ /// NumMatchedMemRefs - The number of matched memref entries. unsigned NumMatchedMemRefs; - /// InputChain/InputFlag - The current chain/flag - SDValue InputChain, InputFlag; + /// InputChain/InputGlue - The current chain/glue + SDValue InputChain, InputGlue; /// HasChainNodesMatched - True if the ChainNodesMatched list is non-empty. - bool HasChainNodesMatched, HasFlagResultNodesMatched; + bool HasChainNodesMatched, HasGlueResultNodesMatched; }; } @@ -2045,17 +2045,17 @@ // pattern. SmallVector MatchedMemRefs; - // These are the current input chain and flag for use when generating nodes. + // These are the current input chain and glue for use when generating nodes. // Various Emit operations change these. For example, emitting a copytoreg // uses and updates these. - SDValue InputChain, InputFlag; + SDValue InputChain, InputGlue; // ChainNodesMatched - If a pattern matches nodes that have input/output // chains, the OPC_EmitMergeInputChains operation is emitted which indicates // which ones they are. The result is captured into this list so that we can // update the chain results when the pattern is complete. SmallVector ChainNodesMatched; - SmallVector FlagResultNodesMatched; + SmallVector GlueResultNodesMatched; DEBUG(errs() << "ISEL: Starting pattern match on root node: "; NodeToMatch->dump(CurDAG); @@ -2159,9 +2159,9 @@ NewEntry.NumRecordedNodes = RecordedNodes.size(); NewEntry.NumMatchedMemRefs = MatchedMemRefs.size(); NewEntry.InputChain = InputChain; - NewEntry.InputFlag = InputFlag; + NewEntry.InputGlue = InputGlue; NewEntry.HasChainNodesMatched = !ChainNodesMatched.empty(); - NewEntry.HasFlagResultNodesMatched = !FlagResultNodesMatched.empty(); + NewEntry.HasGlueResultNodesMatched = !GlueResultNodesMatched.empty(); MatchScopes.push_back(NewEntry); continue; } @@ -2191,10 +2191,10 @@ continue; case OPC_CaptureFlagInput: - // If the current node has an input flag, capture it in InputFlag. + // If the current node has an input glue, capture it in InputGlue. if (N->getNumOperands() != 0 && N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Glue) - InputFlag = N->getOperand(N->getNumOperands()-1); + InputGlue = N->getOperand(N->getNumOperands()-1); continue; case OPC_MoveChild: { @@ -2470,9 +2470,9 @@ InputChain = CurDAG->getCopyToReg(InputChain, NodeToMatch->getDebugLoc(), DestPhysReg, RecordedNodes[RecNo].first, - InputFlag); + InputGlue); - InputFlag = InputChain.getValue(1); + InputGlue = InputChain.getValue(1); continue; } @@ -2502,7 +2502,7 @@ if (EmitNodeInfo & OPFL_Chain) VTs.push_back(MVT::Other); - if (EmitNodeInfo & OPFL_FlagOutput) + if (EmitNodeInfo & OPFL_GlueOutput) VTs.push_back(MVT::Glue); // This is hot code, so optimize the two most common cases of 1 and 2 @@ -2534,7 +2534,7 @@ FirstOpToCopy += (EmitNodeInfo & OPFL_Chain) ? 1 : 0; assert(NodeToMatch->getNumOperands() >= FirstOpToCopy && "Invalid variadic node"); - // Copy all of the variadic operands, not including a potential flag + // Copy all of the variadic operands, not including a potential glue // input. for (unsigned i = FirstOpToCopy, e = NodeToMatch->getNumOperands(); i != e; ++i) { @@ -2544,11 +2544,11 @@ } } - // If this has chain/flag inputs, add them. + // If this has chain/glue inputs, add them. if (EmitNodeInfo & OPFL_Chain) Ops.push_back(InputChain); - if ((EmitNodeInfo & OPFL_FlagInput) && InputFlag.getNode() != 0) - Ops.push_back(InputFlag); + if ((EmitNodeInfo & OPFL_GlueInput) && InputGlue.getNode() != 0) + Ops.push_back(InputGlue); // Create the node. SDNode *Res = 0; @@ -2558,7 +2558,7 @@ Res = CurDAG->getMachineNode(TargetOpc, NodeToMatch->getDebugLoc(), VTList, Ops.data(), Ops.size()); - // Add all the non-flag/non-chain results to the RecordedNodes list. + // Add all the non-glue/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::Glue) break; RecordedNodes.push_back(std::pair(SDValue(Res, i), @@ -2570,16 +2570,16 @@ EmitNodeInfo); } - // If the node had chain/flag results, update our notion of the current - // chain and flag. - if (EmitNodeInfo & OPFL_FlagOutput) { - InputFlag = SDValue(Res, VTs.size()-1); + // If the node had chain/glue results, update our notion of the current + // chain and glue. + if (EmitNodeInfo & OPFL_GlueOutput) { + InputGlue = SDValue(Res, VTs.size()-1); if (EmitNodeInfo & OPFL_Chain) InputChain = SDValue(Res, VTs.size()-2); } else if (EmitNodeInfo & OPFL_Chain) InputChain = SDValue(Res, VTs.size()-1); - // If the OPFL_MemRefs flag is set on this node, slap all of the + // If the OPFL_MemRefs glue is set on this node, slap all of the // accumulated memrefs onto it. // // FIXME: This is vastly incorrect for patterns with multiple outputs @@ -2599,9 +2599,9 @@ // If this was a MorphNodeTo then we're completely done! if (Opcode == OPC_MorphNodeTo) { - // Update chain and flag uses. - UpdateChainsAndFlags(NodeToMatch, InputChain, ChainNodesMatched, - InputFlag, FlagResultNodesMatched, true); + // Update chain and glue uses. + UpdateChainsAndGlue(NodeToMatch, InputChain, ChainNodesMatched, + InputGlue, GlueResultNodesMatched, true); return Res; } @@ -2611,14 +2611,14 @@ case OPC_MarkFlagResults: { unsigned NumNodes = MatcherTable[MatcherIndex++]; - // Read and remember all the flag-result nodes. + // Read and remember all the glue-result nodes. for (unsigned i = 0; i != NumNodes; ++i) { unsigned RecNo = MatcherTable[MatcherIndex++]; if (RecNo & 128) RecNo = GetVBR(RecNo, MatcherTable, MatcherIndex); assert(RecNo < RecordedNodes.size() && "Invalid CheckSame"); - FlagResultNodesMatched.push_back(RecordedNodes[RecNo].first.getNode()); + GlueResultNodesMatched.push_back(RecordedNodes[RecNo].first.getNode()); } continue; } @@ -2650,14 +2650,13 @@ CurDAG->ReplaceAllUsesOfValueWith(SDValue(NodeToMatch, i), Res); } - // If the root node defines a flag, add it to the flag nodes to update - // list. + // If the root node defines glue, add it to the flag nodes to update list. if (NodeToMatch->getValueType(NodeToMatch->getNumValues()-1) == MVT::Glue) - FlagResultNodesMatched.push_back(NodeToMatch); + GlueResultNodesMatched.push_back(NodeToMatch); - // Update chain and flag uses. - UpdateChainsAndFlags(NodeToMatch, InputChain, ChainNodesMatched, - InputFlag, FlagResultNodesMatched, false); + // Update chain and glue uses. + UpdateChainsAndGlue(NodeToMatch, InputChain, ChainNodesMatched, + InputGlue, GlueResultNodesMatched, false); assert(NodeToMatch->use_empty() && "Didn't replace all uses of the node?"); @@ -2694,11 +2693,11 @@ DEBUG(errs() << " Continuing at " << MatcherIndex << "\n"); InputChain = LastScope.InputChain; - InputFlag = LastScope.InputFlag; + InputGlue = LastScope.InputGlue; if (!LastScope.HasChainNodesMatched) ChainNodesMatched.clear(); - if (!LastScope.HasFlagResultNodesMatched) - FlagResultNodesMatched.clear(); + if (!LastScope.HasGlueResultNodesMatched) + GlueResultNodesMatched.clear(); // Check to see what the offset is at the new MatcherIndex. If it is zero // we have reached the end of this scope, otherwise we have another child Modified: llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp?rev=122507&r1=122506&r2=122507&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp Thu Dec 23 11:13:18 2010 @@ -485,8 +485,8 @@ OS << ", TARGET_OPCODE(" << EN->getOpcodeName() << "), 0"; if (EN->hasChain()) OS << "|OPFL_Chain"; - if (EN->hasInFlag()) OS << "|OPFL_FlagInput"; - if (EN->hasOutFlag()) OS << "|OPFL_FlagOutput"; + if (EN->hasInFlag()) OS << "|OPFL_GlueInput"; + if (EN->hasOutFlag()) OS << "|OPFL_GlueOutput"; if (EN->hasMemRefs()) OS << "|OPFL_MemRefs"; if (EN->getNumFixedArityOperands() != -1) OS << "|OPFL_Variadic" << EN->getNumFixedArityOperands(); From sabre at nondot.org Thu Dec 23 11:24:32 2010 From: sabre at nondot.org (Chris Lattner) Date: Thu, 23 Dec 2010 17:24:32 -0000 Subject: [llvm-commits] [llvm] r122509 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAG.h include/llvm/CodeGen/SelectionDAGISel.h include/llvm/CodeGen/SelectionDAGNodes.h lib/CodeGen/SelectionDAG/InstrEmitter.cpp lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp lib/Target/PowerPC/PPCHazardRecognizers.cpp utils/TableGen/DAGISelMatcherEmitter.cpp Message-ID: <20101223172432.8F07A2A6C12C@llvm.org> Author: lattner Date: Thu Dec 23 11:24:32 2010 New Revision: 122509 URL: http://llvm.org/viewvc/llvm-project?rev=122509&view=rev Log: flags -> glue for selectiondag Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.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/SelectionDAGISel.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=122509&r1=122508&r2=122509&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Thu Dec 23 11:24:32 2010 @@ -398,21 +398,21 @@ } // This version of the getCopyToReg method takes an extra operand, which - // indicates that there is potentially an incoming flag value (if Flag is not - // null) and that there should be a flag result. + // indicates that there is potentially an incoming glue value (if Glue is not + // null) and that there should be a glue result. SDValue getCopyToReg(SDValue Chain, DebugLoc dl, unsigned Reg, SDValue N, - SDValue Flag) { + SDValue Glue) { 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); + SDValue Ops[] = { Chain, getRegister(Reg, N.getValueType()), N, Glue }; + return getNode(ISD::CopyToReg, dl, VTs, Ops, Glue.getNode() ? 4 : 3); } // Similar to last getCopyToReg() except parameter Reg is a SDValue SDValue getCopyToReg(SDValue Chain, DebugLoc dl, SDValue Reg, SDValue N, - SDValue Flag) { + SDValue Glue) { SDVTList VTs = getVTList(MVT::Other, MVT::Glue); - SDValue Ops[] = { Chain, Reg, N, Flag }; - return getNode(ISD::CopyToReg, dl, VTs, Ops, Flag.getNode() ? 4 : 3); + SDValue Ops[] = { Chain, Reg, N, Glue }; + return getNode(ISD::CopyToReg, dl, VTs, Ops, Glue.getNode() ? 4 : 3); } SDValue getCopyFromReg(SDValue Chain, DebugLoc dl, unsigned Reg, EVT VT) { @@ -422,13 +422,13 @@ } // This version of the getCopyFromReg method takes an extra operand, which - // indicates that there is potentially an incoming flag value (if Flag is not - // null) and that there should be a flag result. + // indicates that there is potentially an incoming glue value (if Glue is not + // null) and that there should be a glue result. SDValue getCopyFromReg(SDValue Chain, DebugLoc dl, unsigned Reg, EVT VT, - SDValue Flag) { + SDValue Glue) { 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); + SDValue Ops[] = { Chain, getRegister(Reg, VT), Glue }; + return getNode(ISD::CopyFromReg, dl, VTs, Ops, Glue.getNode() ? 3 : 2); } SDValue getCondCode(ISD::CondCode Cond); @@ -462,7 +462,7 @@ SDValue getNOT(DebugLoc DL, SDValue Val, EVT VT); /// getCALLSEQ_START - Return a new CALLSEQ_START node, which always must have - /// a flag result (to ensure it's not CSE'd). CALLSEQ_START does not have a + /// a glue 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::Glue); @@ -471,18 +471,18 @@ } /// getCALLSEQ_END - Return a new CALLSEQ_END node, which always must have a - /// flag result (to ensure it's not CSE'd). CALLSEQ_END does not have + /// glue result (to ensure it's not CSE'd). CALLSEQ_END does not have /// a useful DebugLoc. SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, - SDValue InFlag) { + SDValue InGlue) { SDVTList NodeTys = getVTList(MVT::Other, MVT::Glue); SmallVector Ops; Ops.push_back(Chain); Ops.push_back(Op1); Ops.push_back(Op2); - Ops.push_back(InFlag); + Ops.push_back(InGlue); return getNode(ISD::CALLSEQ_END, DebugLoc(), NodeTys, &Ops[0], - (unsigned)Ops.size() - (InFlag.getNode() == 0 ? 1 : 0)); + (unsigned)Ops.size() - (InGlue.getNode() == 0 ? 1 : 0)); } /// getUNDEF - Return an UNDEF node. UNDEF does not have a useful DebugLoc. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h?rev=122509&r1=122508&r2=122509&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h Thu Dec 23 11:24:32 2010 @@ -110,7 +110,7 @@ OPC_RecordChild0, OPC_RecordChild1, OPC_RecordChild2, OPC_RecordChild3, OPC_RecordChild4, OPC_RecordChild5, OPC_RecordChild6, OPC_RecordChild7, OPC_RecordMemRef, - OPC_CaptureFlagInput, + OPC_CaptureGlueInput, OPC_MoveChild, OPC_MoveParent, OPC_CheckSame, @@ -140,12 +140,12 @@ OPC_EmitNodeXForm, OPC_EmitNode, OPC_MorphNodeTo, - OPC_MarkFlagResults, + OPC_MarkGlueResults, OPC_CompleteMatch }; enum { - OPFL_None = 0, // Node has no chain or flag input and isn't variadic. + OPFL_None = 0, // Node has no chain or glue input and isn't variadic. OPFL_Chain = 1, // Node has a chain input. OPFL_GlueInput = 2, // Node has a glue input. OPFL_GlueOutput = 4, // Node has a glue output. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=122509&r1=122508&r2=122509&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Thu Dec 23 11:24:32 2010 @@ -524,9 +524,9 @@ return X; } - /// getFlaggedNode - If this node has a flag operand, return the node - /// to which the flag operand points. Otherwise return NULL. - SDNode *getFlaggedNode() const { + /// getGluedNode - If this node has a glue operand, return the node + /// to which the glue operand points. Otherwise return NULL. + SDNode *getGluedNode() const { if (getNumOperands() != 0 && getOperand(getNumOperands()-1).getValueType() == MVT::Glue) return getOperand(getNumOperands()-1).getNode(); @@ -534,14 +534,14 @@ } // If this is a pseudo op, like copyfromreg, look to see if there is a - // real target node flagged to it. If so, return the target node. - const SDNode *getFlaggedMachineNode() const { + // real target node glued to it. If so, return the target node. + const SDNode *getGluedMachineNode() const { const SDNode *FoundNode = this; - // Climb up flag edges until a machine-opcode node is found, or the + // Climb up glue edges until a machine-opcode node is found, or the // end of the chain is reached. while (!FoundNode->isMachineOpcode()) { - const SDNode *N = FoundNode->getFlaggedNode(); + const SDNode *N = FoundNode->getGluedNode(); if (!N) break; FoundNode = N; } @@ -549,9 +549,9 @@ return FoundNode; } - /// getFlaggedUser - If this node has a flag value with a user, return + /// getGluedUser - If this node has a glue value with a user, return /// the user (there is at most one). Otherwise return NULL. - SDNode *getFlaggedUser() const { + SDNode *getGluedUser() const { for (use_iterator UI = use_begin(), UE = use_end(); UI != UE; ++UI) if (UI.getUse().get().getValueType() == MVT::Glue) return *UI; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp?rev=122509&r1=122508&r2=122509&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp Thu Dec 23 11:24:32 2010 @@ -31,7 +31,7 @@ using namespace llvm; /// CountResults - The results of target nodes have register or immediate -/// operands first, then an optional chain, and optional flag operands (which do +/// operands first, then an optional chain, and optional glue operands (which do /// not go into the resulting MachineInstr). unsigned InstrEmitter::CountResults(SDNode *Node) { unsigned N = Node->getNumValues(); @@ -43,7 +43,7 @@ } /// CountOperands - The inputs to target nodes have any actual inputs first, -/// followed by an optional chain operand, then an optional flag operand. +/// followed by an optional chain operand, then an optional glue operand. /// Compute the number of actual operands that will go into the resulting /// MachineInstr. unsigned InstrEmitter::CountOperands(SDNode *Node) { @@ -265,7 +265,7 @@ bool IsDebug, bool IsClone, bool IsCloned) { assert(Op.getValueType() != MVT::Other && Op.getValueType() != MVT::Glue && - "Chain and flag operands should occur at end of operand list!"); + "Chain and glue operands should occur at end of operand list!"); // Get/emit the operand. unsigned VReg = getVR(Op, VRBaseMap); assert(TargetRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); @@ -378,7 +378,7 @@ } else { assert(Op.getValueType() != MVT::Other && Op.getValueType() != MVT::Glue && - "Chain and flag operands should occur at end of operand list!"); + "Chain and glue operands should occur at end of operand list!"); AddRegisterOperand(MI, Op, IIOpNum, II, VRBaseMap, IsDebug, IsClone, IsCloned); } @@ -674,7 +674,7 @@ Node->getValueType(Node->getNumValues()-1) == MVT::Glue) { // First, collect all used registers. SmallVector UsedRegs; - for (SDNode *F = Node->getFlaggedUser(); F; F = F->getFlaggedUser()) + for (SDNode *F = Node->getGluedUser(); F; F = F->getGluedUser()) if (F->getOpcode() == ISD::CopyFromReg) UsedRegs.push_back(cast(F->getOperand(1))->getReg()); else { @@ -727,16 +727,16 @@ EmitCopyFromReg(Node, i, IsClone, IsCloned, Reg, VRBaseMap); // If there are no uses, mark the register as dead now, so that // 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. + // node has a Glue value, for the benefit of targets still using + // Glue for values in physregs. else if (Node->getValueType(Node->getNumValues()-1) != MVT::Glue) MI->addRegisterDead(Reg, TRI); } } // 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. + // implicit def as dead. If the node has any glue outputs, we don't do this + // because we don't know what implicit defs are being used by glued nodes. if (Node->getValueType(Node->getNumValues()-1) != MVT::Glue) if (const unsigned *IDList = II.getImplicitDefs()) { for (unsigned i = NumResults, e = II.getNumDefs()+II.getNumImplicitDefs(); @@ -794,7 +794,7 @@ case ISD::INLINEASM: { unsigned NumOps = Node->getNumOperands(); if (Node->getOperand(NumOps-1).getValueType() == MVT::Glue) - --NumOps; // Ignore the flag operand. + --NumOps; // Ignore the glue operand. // Create the inline asm machine instruction. MachineInstr *MI = BuildMI(*MF, Node->getDebugLoc(), Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp?rev=122509&r1=122508&r2=122509&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp Thu Dec 23 11:24:32 2010 @@ -205,7 +205,7 @@ /// CopyAndMoveSuccessors - Clone the specified node and move its scheduled /// successors to the newly created node. SUnit *ScheduleDAGFast::CopyAndMoveSuccessors(SUnit *SU) { - if (SU->getNode()->getFlaggedNode()) + if (SU->getNode()->getGluedNode()) return NULL; SDNode *N = SU->getNode(); @@ -476,12 +476,12 @@ } } - for (SDNode *Node = SU->getNode(); Node; Node = Node->getFlaggedNode()) { + for (SDNode *Node = SU->getNode(); Node; Node = Node->getGluedNode()) { if (Node->getOpcode() == ISD::INLINEASM) { // Inline asm can clobber physical defs. unsigned NumOps = Node->getNumOperands(); if (Node->getOperand(NumOps-1).getValueType() == MVT::Glue) - --NumOps; // Ignore the flag operand. + --NumOps; // Ignore the glue operand. for (unsigned i = InlineAsm::Op_FirstOperand; i != NumOps;) { unsigned Flags = Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=122509&r1=122508&r2=122509&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Thu Dec 23 11:24:32 2010 @@ -407,7 +407,7 @@ static bool isOperandOf(const SUnit *SU, SDNode *N) { for (const SDNode *SUNode = SU->getNode(); SUNode; - SUNode = SUNode->getFlaggedNode()) { + SUNode = SUNode->getGluedNode()) { if (SUNode->isOperandOf(N)) return true; } @@ -417,7 +417,7 @@ /// CopyAndMoveSuccessors - Clone the specified node and move its scheduled /// successors to the newly created node. SUnit *ScheduleDAGRRList::CopyAndMoveSuccessors(SUnit *SU) { - if (SU->getNode()->getFlaggedNode()) + if (SU->getNode()->getGluedNode()) return NULL; SDNode *N = SU->getNode(); @@ -700,12 +700,12 @@ RegAdded, LRegs, TRI); } - for (SDNode *Node = SU->getNode(); Node; Node = Node->getFlaggedNode()) { + for (SDNode *Node = SU->getNode(); Node; Node = Node->getGluedNode()) { if (Node->getOpcode() == ISD::INLINEASM) { // Inline asm can clobber physical defs. unsigned NumOps = Node->getNumOperands(); if (Node->getOperand(NumOps-1).getValueType() == MVT::Glue) - --NumOps; // Ignore the flag operand. + --NumOps; // Ignore the glue operand. for (unsigned i = InlineAsm::Op_FirstOperand; i != NumOps;) { unsigned Flags = @@ -1752,7 +1752,7 @@ const unsigned *ImpDefs = TII->get(N->getMachineOpcode()).getImplicitDefs(); assert(ImpDefs && "Caller should check hasPhysRegDefs"); for (const SDNode *SUNode = SU->getNode(); SUNode; - SUNode = SUNode->getFlaggedNode()) { + SUNode = SUNode->getGluedNode()) { if (!SUNode->isMachineOpcode()) continue; const unsigned *SUImpDefs = @@ -1908,7 +1908,7 @@ continue; SDNode *Node = SU->getNode(); - if (!Node || !Node->isMachineOpcode() || SU->getNode()->getFlaggedNode()) + if (!Node || !Node->isMachineOpcode() || SU->getNode()->getGluedNode()) continue; bool isLiveOut = hasOnlyLiveOutUses(SU); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp?rev=122509&r1=122508&r2=122509&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp Thu Dec 23 11:24:32 2010 @@ -109,29 +109,28 @@ } } -static void AddFlags(SDNode *N, SDValue Flag, bool AddFlag, - SelectionDAG *DAG) { +static void AddGlue(SDNode *N, SDValue Glue, bool AddGlue, SelectionDAG *DAG) { SmallVector VTs; - SDNode *FlagDestNode = Flag.getNode(); + SDNode *GlueDestNode = Glue.getNode(); - // Don't add a flag from a node to itself. - if (FlagDestNode == N) return; + // Don't add glue from a node to itself. + if (GlueDestNode == N) return; - // Don't add a flag to something which already has a flag. + // Don't add glue to something which already has glue. 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) + if (AddGlue) VTs.push_back(MVT::Glue); SmallVector Ops; for (unsigned I = 0, E = N->getNumOperands(); I != E; ++I) Ops.push_back(N->getOperand(I)); - if (FlagDestNode) - Ops.push_back(Flag); + if (GlueDestNode) + Ops.push_back(Glue); SDVTList VTList = DAG->getVTList(&VTs[0], VTs.size()); MachineSDNode::mmo_iterator Begin = 0, End = 0; @@ -150,7 +149,7 @@ MN->setMemRefs(Begin, End); } -/// ClusterNeighboringLoads - Force nearby loads together by "flagging" them. +/// ClusterNeighboringLoads - Force nearby loads together by "gluing" them. /// This function finds loads of the same base and different offsets. If the /// offsets are not far apart (target specific), it add MVT::Glue inputs and /// outputs to ensure they are scheduled together and in order. This @@ -217,17 +216,17 @@ // 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); + AddGlue(Lead, SDValue(0, 0), true, DAG); - SDValue InFlag = SDValue(Lead, Lead->getNumValues() - 1); + SDValue InGlue = SDValue(Lead, Lead->getNumValues() - 1); for (unsigned I = 1, E = Loads.size(); I != E; ++I) { - bool OutFlag = I < E - 1; + bool OutGlue = I < E - 1; SDNode *Load = Loads[I]; - AddFlags(Load, InFlag, OutFlag, DAG); + AddGlue(Load, InGlue, OutGlue, DAG); - if (OutFlag) - InFlag = SDValue(Load, Load->getNumValues() - 1); + if (OutGlue) + InGlue = SDValue(Load, Load->getNumValues() - 1); ++LoadsClustered; } @@ -290,11 +289,11 @@ SUnit *NodeSUnit = NewSUnit(NI); - // See if anything is flagged to this node, if so, add them to flagged - // nodes. Nodes can have at most one flag input and one flag output. Flags - // are required to be the last operand and result of a node. + // See if anything is glued to this node, if so, add them to glued + // nodes. Nodes can have at most one glue input and one glue output. Glue + // is required to be the last operand and result of a node. - // Scan up to find flagged preds. + // Scan up to find glued preds. SDNode *N = NI; while (N->getNumOperands() && N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Glue) { @@ -305,17 +304,17 @@ NodeSUnit->isCall = true; } - // Scan down to find any flagged succs. + // Scan down to find any glued succs. N = NI; while (N->getValueType(N->getNumValues()-1) == MVT::Glue) { - SDValue FlagVal(N, N->getNumValues()-1); + SDValue GlueVal(N, N->getNumValues()-1); - // There are either zero or one users of the Flag result. - bool HasFlagUse = false; + // There are either zero or one users of the Glue result. + bool HasGlueUse = false; for (SDNode::use_iterator UI = N->use_begin(), E = N->use_end(); UI != E; ++UI) - if (FlagVal.isOperandOf(*UI)) { - HasFlagUse = true; + if (GlueVal.isOperandOf(*UI)) { + HasGlueUse = true; assert(N->getNodeId() == -1 && "Node already inserted!"); N->setNodeId(NodeSUnit->NodeNum); N = *UI; @@ -323,11 +322,11 @@ NodeSUnit->isCall = true; break; } - if (!HasFlagUse) break; + if (!HasGlueUse) break; } - // If there are flag operands involved, N is now the bottom-most node - // of the sequence of nodes that are flagged together. + // If there are glue operands involved, N is now the bottom-most node + // of the sequence of nodes that are glued together. // Update the SUnit. NodeSUnit->setNode(N); assert(N->getNodeId() == -1 && "Node already inserted!"); @@ -363,7 +362,7 @@ } // Find all predecessors and successors of the group. - for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) { + for (SDNode *N = SU->getNode(); N; N = N->getGluedNode()) { if (N->isMachineOpcode() && TII->get(N->getMachineOpcode()).getImplicitDefs()) { SU->hasPhysRegClobbers = true; @@ -382,7 +381,7 @@ if (OpSU == SU) continue; // In the same group. EVT OpVT = N->getOperand(i).getValueType(); - assert(OpVT != MVT::Glue && "Flagged nodes should be in same sunit!"); + assert(OpVT != MVT::Glue && "Glued nodes should be in same sunit!"); bool isChain = OpVT == MVT::Other; unsigned PhysReg = 0; @@ -417,7 +416,7 @@ /// BuildSchedGraph - Build the SUnit graph from the selection dag that we /// are input. This SUnit graph is similar to the SelectionDAG, but /// excludes nodes that aren't interesting to scheduling, and represents -/// flagged together nodes with a single SUnit. +/// glued together nodes with a single SUnit. void ScheduleDAGSDNodes::BuildSchedGraph(AliasAnalysis *AA) { // Cluster certain nodes which should be scheduled together. ClusterNodes(); @@ -440,9 +439,9 @@ } // Compute the latency for the node. We use the sum of the latencies for - // all nodes flagged together into this SUnit. + // all nodes glued together into this SUnit. SU->Latency = 0; - for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) + for (SDNode *N = SU->getNode(); N; N = N->getGluedNode()) if (N->isMachineOpcode()) SU->Latency += TII->getInstrLatency(InstrItins, N); } @@ -482,14 +481,14 @@ SU->getNode()->dump(DAG); dbgs() << "\n"; - SmallVector FlaggedNodes; - for (SDNode *N = SU->getNode()->getFlaggedNode(); N; N = N->getFlaggedNode()) - FlaggedNodes.push_back(N); - while (!FlaggedNodes.empty()) { + SmallVector GluedNodes; + for (SDNode *N = SU->getNode()->getGluedNode(); N; N = N->getGluedNode()) + GluedNodes.push_back(N); + while (!GluedNodes.empty()) { dbgs() << " "; - FlaggedNodes.back()->dump(DAG); + GluedNodes.back()->dump(DAG); dbgs() << "\n"; - FlaggedNodes.pop_back(); + GluedNodes.pop_back(); } } @@ -573,25 +572,25 @@ } // For pre-regalloc scheduling, create instructions corresponding to the - // SDNode and any flagged SDNodes and append them to the block. + // SDNode and any glued SDNodes and append them to the block. if (!SU->getNode()) { // Emit a copy. EmitPhysRegCopy(SU, CopyVRBaseMap); continue; } - SmallVector FlaggedNodes; - for (SDNode *N = SU->getNode()->getFlaggedNode(); N; - N = N->getFlaggedNode()) - FlaggedNodes.push_back(N); - while (!FlaggedNodes.empty()) { - SDNode *N = FlaggedNodes.back(); - Emitter.EmitNode(FlaggedNodes.back(), SU->OrigNode != SU, SU->isCloned, + SmallVector GluedNodes; + for (SDNode *N = SU->getNode()->getGluedNode(); N; + N = N->getGluedNode()) + GluedNodes.push_back(N); + while (!GluedNodes.empty()) { + SDNode *N = GluedNodes.back(); + Emitter.EmitNode(GluedNodes.back(), SU->OrigNode != SU, SU->isCloned, VRBaseMap); // Remember the source order of the inserted instruction. if (HasDbg) ProcessSourceNode(N, DAG, Emitter, VRBaseMap, Orders, Seen); - FlaggedNodes.pop_back(); + GluedNodes.pop_back(); } Emitter.EmitNode(SU->getNode(), SU->OrigNode != SU, SU->isCloned, VRBaseMap); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=122509&r1=122508&r2=122509&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Dec 23 11:24:32 2010 @@ -2190,7 +2190,7 @@ MatchedMemRefs.push_back(cast(N)->getMemOperand()); continue; - case OPC_CaptureFlagInput: + case OPC_CaptureGlueInput: // If the current node has an input glue, capture it in InputGlue. if (N->getNumOperands() != 0 && N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Glue) @@ -2608,7 +2608,7 @@ continue; } - case OPC_MarkFlagResults: { + case OPC_MarkGlueResults: { unsigned NumNodes = MatcherTable[MatcherIndex++]; // Read and remember all the glue-result nodes. @@ -2650,7 +2650,7 @@ CurDAG->ReplaceAllUsesOfValueWith(SDValue(NodeToMatch, i), Res); } - // If the root node defines glue, add it to the flag nodes to update list. + // If the root node defines glue, add it to the glue nodes to update list. if (NodeToMatch->getValueType(NodeToMatch->getNumValues()-1) == MVT::Glue) GlueResultNodesMatched.push_back(NodeToMatch); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp?rev=122509&r1=122508&r2=122509&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp Thu Dec 23 11:24:32 2010 @@ -273,14 +273,14 @@ raw_string_ostream O(s); O << "SU(" << SU->NodeNum << "): "; if (SU->getNode()) { - SmallVector FlaggedNodes; - for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) - FlaggedNodes.push_back(N); - while (!FlaggedNodes.empty()) { + SmallVector GluedNodes; + for (SDNode *N = SU->getNode(); N; N = N->getGluedNode()) + GluedNodes.push_back(N); + while (!GluedNodes.empty()) { O << DOTGraphTraits - ::getSimpleNodeLabel(FlaggedNodes.back(), DAG); - FlaggedNodes.pop_back(); - if (!FlaggedNodes.empty()) + ::getSimpleNodeLabel(GluedNodes.back(), DAG); + GluedNodes.pop_back(); + if (!GluedNodes.empty()) O << "\n "; } } else { Modified: llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp?rev=122509&r1=122508&r2=122509&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp Thu Dec 23 11:24:32 2010 @@ -123,7 +123,7 @@ /// pipeline flush. ScheduleHazardRecognizer::HazardType PPCHazardRecognizer970:: getHazardType(SUnit *SU) { - const SDNode *Node = SU->getNode()->getFlaggedMachineNode(); + const SDNode *Node = SU->getNode()->getGluedMachineNode(); bool isFirst, isSingle, isCracked, isLoad, isStore; PPCII::PPC970_Unit InstrType = GetInstrType(Node->getOpcode(), isFirst, isSingle, isCracked, @@ -222,7 +222,7 @@ } void PPCHazardRecognizer970::EmitInstruction(SUnit *SU) { - const SDNode *Node = SU->getNode()->getFlaggedMachineNode(); + const SDNode *Node = SU->getNode()->getGluedMachineNode(); bool isFirst, isSingle, isCracked, isLoad, isStore; PPCII::PPC970_Unit InstrType = GetInstrType(Node->getOpcode(), isFirst, isSingle, isCracked, Modified: llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp?rev=122509&r1=122508&r2=122509&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp Thu Dec 23 11:24:32 2010 @@ -221,7 +221,7 @@ return 1; case Matcher::CaptureGlueInput: - OS << "OPC_CaptureFlagInput,\n"; + OS << "OPC_CaptureGlueInput,\n"; return 1; case Matcher::MoveChild: @@ -533,7 +533,7 @@ } case Matcher::MarkGlueResults: { const MarkGlueResultsMatcher *CFR = cast(N); - OS << "OPC_MarkFlagResults, " << CFR->getNumNodes() << ", "; + OS << "OPC_MarkGlueResults, " << CFR->getNumNodes() << ", "; unsigned NumOperandBytes = 0; for (unsigned i = 0, e = CFR->getNumNodes(); i != e; ++i) NumOperandBytes += EmitVBRValue(CFR->getNode(i), OS); @@ -742,7 +742,7 @@ case Matcher::RecordNode: OS << "OPC_RecordNode"; break; case Matcher::RecordChild: OS << "OPC_RecordChild"; break; case Matcher::RecordMemRef: OS << "OPC_RecordMemRef"; break; - case Matcher::CaptureGlueInput: OS << "OPC_CaptureFlagInput"; break; + case Matcher::CaptureGlueInput: OS << "OPC_CaptureGlueInput"; break; case Matcher::MoveChild: OS << "OPC_MoveChild"; break; case Matcher::MoveParent: OS << "OPC_MoveParent"; break; case Matcher::CheckSame: OS << "OPC_CheckSame"; break; @@ -771,7 +771,7 @@ case Matcher::EmitNode: OS << "OPC_EmitNode"; break; case Matcher::MorphNodeTo: OS << "OPC_MorphNodeTo"; break; case Matcher::EmitNodeXForm: OS << "OPC_EmitNodeXForm"; break; - case Matcher::MarkGlueResults: OS << "OPC_MarkFlagResults"; break; + case Matcher::MarkGlueResults: OS << "OPC_MarkGlueResults"; break; case Matcher::CompleteMatch: OS << "OPC_CompleteMatch"; break; } From anton at korobeynikov.info Thu Dec 23 11:30:33 2010 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Thu, 23 Dec 2010 20:30:33 +0300 Subject: [llvm-commits] [llvm] r122507 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAGISel.h lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp utils/TableGen/DAGISelMatcherEmitter.cpp In-Reply-To: <20101223171318.5E0962A6C12C@llvm.org> References: <20101223171318.5E0962A6C12C@llvm.org> Message-ID: > - ? ?OPFL_None ? ? ? = 0, ? ? // Node has no chain or flag input and isn't variadic. > + ? ?OPFL_None ? ? ? = 0, ?// Node has no chain or flag input and isn't variadic. flag -> glue? -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From sabre at nondot.org Thu Dec 23 12:28:42 2010 From: sabre at nondot.org (Chris Lattner) Date: Thu, 23 Dec 2010 18:28:42 -0000 Subject: [llvm-commits] [llvm] r122513 - in /llvm/trunk: include/llvm/Target/ 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/ utils/TableGen/ Message-ID: <20101223182842.4D2B92A6C12C@llvm.org> Author: lattner Date: Thu Dec 23 12:28:41 2010 New Revision: 122513 URL: http://llvm.org/viewvc/llvm-project?rev=122513&view=rev Log: Flag -> Glue, the ongoing saga Modified: llvm/trunk/include/llvm/Target/TargetSelectionDAG.td llvm/trunk/lib/Target/ARM/ARMInstrInfo.td llvm/trunk/lib/Target/ARM/ARMInstrThumb.td llvm/trunk/lib/Target/ARM/ARMInstrVFP.td llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.td llvm/trunk/lib/Target/Blackfin/BlackfinInstrInfo.td llvm/trunk/lib/Target/CellSPU/SPUNodes.td llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td llvm/trunk/lib/Target/Mips/MipsInstrFPU.td llvm/trunk/lib/Target/Mips/MipsInstrInfo.td llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td llvm/trunk/lib/Target/X86/X86InstrFPStack.td llvm/trunk/lib/Target/X86/X86InstrInfo.td llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp llvm/trunk/utils/TableGen/CodeGenTarget.cpp llvm/trunk/utils/TableGen/CodeGenTarget.h llvm/trunk/utils/TableGen/DAGISelMatcher.cpp llvm/trunk/utils/TableGen/DAGISelMatcher.h llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp llvm/trunk/utils/TableGen/DAGISelMatcherOpt.cpp Modified: llvm/trunk/include/llvm/Target/TargetSelectionDAG.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetSelectionDAG.td?rev=122513&r1=122512&r2=122513&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetSelectionDAG.td (original) +++ llvm/trunk/include/llvm/Target/TargetSelectionDAG.td Thu Dec 23 12:28:41 2010 @@ -216,9 +216,9 @@ def SDNPCommutative : SDNodeProperty; // X op Y == Y op X def SDNPAssociative : SDNodeProperty; // (X op Y) op Z == X op (Y op Z) def SDNPHasChain : SDNodeProperty; // R/W chain operand and result -def SDNPOutFlag : SDNodeProperty; // Write a flag result -def SDNPInFlag : SDNodeProperty; // Read a flag operand -def SDNPOptInFlag : SDNodeProperty; // Optionally read a flag operand +def SDNPOutGlue : SDNodeProperty; // Write a flag result +def SDNPInGlue : SDNodeProperty; // Read a flag operand +def SDNPOptInGlue : SDNodeProperty; // Optionally read a flag operand def SDNPMayStore : SDNodeProperty; // May write to memory, sets 'mayStore'. def SDNPMayLoad : SDNodeProperty; // May read memory, sets 'mayLoad'. def SDNPSideEffect : SDNodeProperty; // Sets 'HasUnmodelledSideEffects'. @@ -312,13 +312,13 @@ def xor : SDNode<"ISD::XOR" , SDTIntBinOp, [SDNPCommutative, SDNPAssociative]>; def addc : SDNode<"ISD::ADDC" , SDTIntBinOp, - [SDNPCommutative, SDNPOutFlag]>; + [SDNPCommutative, SDNPOutGlue]>; def adde : SDNode<"ISD::ADDE" , SDTIntBinOp, - [SDNPCommutative, SDNPOutFlag, SDNPInFlag]>; + [SDNPCommutative, SDNPOutGlue, SDNPInGlue]>; def subc : SDNode<"ISD::SUBC" , SDTIntBinOp, - [SDNPOutFlag]>; + [SDNPOutGlue]>; def sube : SDNode<"ISD::SUBE" , SDTIntBinOp, - [SDNPOutFlag, SDNPInFlag]>; + [SDNPOutGlue, SDNPInGlue]>; def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>; def bswap : SDNode<"ISD::BSWAP" , SDTIntUnaryOp>; Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=122513&r1=122512&r2=122513&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Thu Dec 23 12:28:41 2010 @@ -72,30 +72,30 @@ def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>; def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart, - [SDNPHasChain, SDNPOutFlag]>; + [SDNPHasChain, SDNPOutGlue]>; def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag, + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>; def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag, + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>; def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag, + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>; def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone, - [SDNPHasChain, SDNPOptInFlag]>; + [SDNPHasChain, SDNPOptInGlue]>; def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov, - [SDNPInFlag]>; + [SDNPInGlue]>; def ARMcneg : SDNode<"ARMISD::CNEG", SDT_ARMCMov, - [SDNPInFlag]>; + [SDNPInGlue]>; def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond, - [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>; def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT, [SDNPHasChain]>; @@ -106,16 +106,16 @@ [SDNPHasChain]>; def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp, - [SDNPOutFlag]>; + [SDNPOutGlue]>; def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp, - [SDNPOutFlag, SDNPCommutative]>; + [SDNPOutGlue, SDNPCommutative]>; def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>; -def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>; -def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>; -def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>; +def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>; +def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>; +def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInGlue ]>; def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>; def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", @@ -136,7 +136,7 @@ def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>; def ARMtcret : SDNode<"ARMISD::TC_RETURN", SDT_ARMTCRET, - [SDNPHasChain, SDNPOptInFlag, SDNPVariadic]>; + [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; def ARMbfi : SDNode<"ARMISD::BFI", SDT_ARMBFI>; Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=122513&r1=122512&r2=122513&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Thu Dec 23 12:28:41 2010 @@ -16,7 +16,7 @@ // def ARMtcall : SDNode<"ARMISD::tCALL", SDT_ARMcall, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag, + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>; def imm_neg_XFORM : SDNodeXForm; def arm_sitof : SDNode<"ARMISD::SITOF", SDT_ITOF>; def arm_uitof : SDNode<"ARMISD::UITOF", SDT_ITOF>; -def arm_fmstat : SDNode<"ARMISD::FMSTAT", SDTNone, [SDNPInFlag, SDNPOutFlag]>; -def arm_cmpfp : SDNode<"ARMISD::CMPFP", SDT_ARMCmp, [SDNPOutFlag]>; -def arm_cmpfp0 : SDNode<"ARMISD::CMPFPw0", SDT_CMPFP0, [SDNPOutFlag]>; +def arm_fmstat : SDNode<"ARMISD::FMSTAT", SDTNone, [SDNPInGlue, SDNPOutGlue]>; +def arm_cmpfp : SDNode<"ARMISD::CMPFP", SDT_ARMCmp, [SDNPOutGlue]>; +def arm_cmpfp0 : SDNode<"ARMISD::CMPFPw0", SDT_CMPFP0, [SDNPOutGlue]>; def arm_fmdrr : SDNode<"ARMISD::VMOVDRR", SDT_VMOVDRR>; Modified: llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.td?rev=122513&r1=122512&r2=122513&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.td (original) +++ llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.td Thu Dec 23 12:28:41 2010 @@ -27,7 +27,7 @@ def Alpha_rellit : SDNode<"AlphaISD::RelLit", SDTIntBinOp, [SDNPMayLoad]>; def retflag : SDNode<"AlphaISD::RET_FLAG", SDTNone, - [SDNPHasChain, SDNPOptInFlag]>; + [SDNPHasChain, SDNPOptInGlue]>; // These are target-independent nodes, but have target-specific formats. def SDT_AlphaCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i64> ]>; @@ -35,9 +35,9 @@ SDTCisVT<1, i64> ]>; def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_AlphaCallSeqStart, - [SDNPHasChain, SDNPOutFlag]>; + [SDNPHasChain, SDNPOutGlue]>; def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_AlphaCallSeqEnd, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; //******************** //Paterns for matching Modified: llvm/trunk/lib/Target/Blackfin/BlackfinInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Blackfin/BlackfinInstrInfo.td?rev=122513&r1=122512&r2=122513&view=diff ============================================================================== --- llvm/trunk/lib/Target/Blackfin/BlackfinInstrInfo.td (original) +++ llvm/trunk/lib/Target/Blackfin/BlackfinInstrInfo.td Thu Dec 23 12:28:41 2010 @@ -23,17 +23,17 @@ SDTCisVT<1, i32> ]>; def BfinCallseqStart : SDNode<"ISD::CALLSEQ_START", SDT_BfinCallSeqStart, - [SDNPHasChain, SDNPOutFlag]>; + [SDNPHasChain, SDNPOutGlue]>; def BfinCallseqEnd : SDNode<"ISD::CALLSEQ_END", SDT_BfinCallSeqEnd, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; def SDT_BfinCall : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; def BfinCall : SDNode<"BFISD::CALL", SDT_BfinCall, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag, + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>; def BfinRet: SDNode<"BFISD::RET_FLAG", SDTNone, - [SDNPHasChain, SDNPOptInFlag]>; + [SDNPHasChain, SDNPOptInGlue]>; def BfinWrapper: SDNode<"BFISD::Wrapper", SDTIntUnaryOp>; Modified: llvm/trunk/lib/Target/CellSPU/SPUNodes.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUNodes.td?rev=122513&r1=122512&r2=122513&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUNodes.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPUNodes.td Thu Dec 23 12:28:41 2010 @@ -19,16 +19,16 @@ def SPUshufmask : SDNode<"SPUISD::SHUFFLE_MASK", SPU_GenControl, []>; def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPUCallSeq, - [SDNPHasChain, SDNPOutFlag]>; + [SDNPHasChain, SDNPOutGlue]>; def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPUCallSeq, - [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>; //===----------------------------------------------------------------------===// // Operand constraints: //===----------------------------------------------------------------------===// def SDT_SPUCall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>; def SPUcall : SDNode<"SPUISD::CALL", SDT_SPUCall, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag, + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>; // Operand type constraints for vector shuffle/permute operations @@ -156,4 +156,4 @@ //===----------------------------------------------------------------------===// def retflag : SDNode<"SPUISD::RET_FLAG", SDTNone, - [SDNPHasChain, SDNPOptInFlag]>; + [SDNPHasChain, SDNPOptInGlue]>; Modified: llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td?rev=122513&r1=122512&r2=122513&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td Thu Dec 23 12:28:41 2010 @@ -28,21 +28,21 @@ //===----------------------------------------------------------------------===// def MBlazeRet : SDNode<"MBlazeISD::Ret", SDT_MBlazeRet, - [SDNPHasChain, SDNPOptInFlag]>; + [SDNPHasChain, SDNPOptInGlue]>; def MBlazeIRet : SDNode<"MBlazeISD::IRet", SDT_MBlazeIRet, - [SDNPHasChain, SDNPOptInFlag]>; + [SDNPHasChain, SDNPOptInGlue]>; def MBlazeJmpLink : SDNode<"MBlazeISD::JmpLink",SDT_MBlazeJmpLink, - [SDNPHasChain,SDNPOptInFlag,SDNPOutFlag, + [SDNPHasChain,SDNPOptInGlue,SDNPOutGlue, SDNPVariadic]>; def MBWrapper : SDNode<"MBlazeISD::Wrap", SDTIntUnaryOp>; def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MBCallSeqStart, - [SDNPHasChain, SDNPOutFlag]>; + [SDNPHasChain, SDNPOutGlue]>; def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MBCallSeqEnd, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; //===----------------------------------------------------------------------===// // MBlaze Instruction Predicate Definitions. Modified: llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td?rev=122513&r1=122512&r2=122513&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td (original) +++ llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td Thu Dec 23 12:28:41 2010 @@ -40,28 +40,28 @@ // MSP430 Specific Node Definitions. //===----------------------------------------------------------------------===// def MSP430retflag : SDNode<"MSP430ISD::RET_FLAG", SDTNone, - [SDNPHasChain, SDNPOptInFlag]>; + [SDNPHasChain, SDNPOptInGlue]>; def MSP430retiflag : SDNode<"MSP430ISD::RETI_FLAG", SDTNone, - [SDNPHasChain, SDNPOptInFlag]>; + [SDNPHasChain, SDNPOptInGlue]>; def MSP430rra : SDNode<"MSP430ISD::RRA", SDTIntUnaryOp, []>; def MSP430rla : SDNode<"MSP430ISD::RLA", SDTIntUnaryOp, []>; def MSP430rrc : SDNode<"MSP430ISD::RRC", SDTIntUnaryOp, []>; def MSP430call : SDNode<"MSP430ISD::CALL", SDT_MSP430Call, - [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag, SDNPVariadic]>; + [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>; def MSP430callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MSP430CallSeqStart, - [SDNPHasChain, SDNPOutFlag]>; + [SDNPHasChain, SDNPOutGlue]>; def MSP430callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MSP430CallSeqEnd, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; def MSP430Wrapper : SDNode<"MSP430ISD::Wrapper", SDT_MSP430Wrapper>; -def MSP430cmp : SDNode<"MSP430ISD::CMP", SDT_MSP430Cmp, [SDNPOutFlag]>; +def MSP430cmp : SDNode<"MSP430ISD::CMP", SDT_MSP430Cmp, [SDNPOutGlue]>; def MSP430brcc : SDNode<"MSP430ISD::BR_CC", SDT_MSP430BrCC, - [SDNPHasChain, SDNPInFlag]>; + [SDNPHasChain, SDNPInGlue]>; def MSP430selectcc: SDNode<"MSP430ISD::SELECT_CC", SDT_MSP430SelectCC, - [SDNPInFlag]>; + [SDNPInGlue]>; def MSP430shl : SDNode<"MSP430ISD::SHL", SDT_MSP430Shift, []>; def MSP430sra : SDNode<"MSP430ISD::SRA", SDT_MSP430Shift, []>; def MSP430srl : SDNode<"MSP430ISD::SRL", SDT_MSP430Shift, []>; Modified: llvm/trunk/lib/Target/Mips/MipsInstrFPU.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrFPU.td?rev=122513&r1=122512&r2=122513&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrFPU.td (original) +++ llvm/trunk/lib/Target/Mips/MipsInstrFPU.td Thu Dec 23 12:28:41 2010 @@ -32,7 +32,7 @@ def SDT_MipsFPSelectCC : SDTypeProfile<1, 4, [SDTCisInt<1>, SDTCisInt<4>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>]>; -def MipsFPRound : SDNode<"MipsISD::FPRound", SDTFPRoundOp, [SDNPOptInFlag]>; +def MipsFPRound : SDNode<"MipsISD::FPRound", SDTFPRoundOp, [SDNPOptInGlue]>; def MipsFPBrcond : SDNode<"MipsISD::FPBrcond", SDT_MipsFPBrcond, [SDNPHasChain]>; def MipsFPCmp : SDNode<"MipsISD::FPCmp", SDT_MipsFPCmp>; Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.td?rev=122513&r1=122512&r2=122513&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrInfo.td (original) +++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.td Thu Dec 23 12:28:41 2010 @@ -29,7 +29,7 @@ // Call def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink, - [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag, + [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>; // Hi and Lo nodes are used to handle global addresses. Used on @@ -41,13 +41,13 @@ // Return def MipsRet : SDNode<"MipsISD::Ret", SDT_MipsRet, [SDNPHasChain, - SDNPOptInFlag]>; + SDNPOptInGlue]>; // These are target-independent nodes, but have target-specific formats. def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MipsCallSeqStart, - [SDNPHasChain, SDNPOutFlag]>; + [SDNPHasChain, SDNPOutGlue]>; def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeqEnd, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; // Select Condition Code def MipsSelectCC : SDNode<"MipsISD::SelectCC", SDT_MipsSelectCC>; Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td?rev=122513&r1=122512&r2=122513&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td (original) +++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td Thu Dec 23 12:28:41 2010 @@ -68,17 +68,17 @@ // This sequence is used for long double->int conversions. It changes the // bits in the FPSCR which is not modelled. def PPCmffs : SDNode<"PPCISD::MFFS", SDTypeProfile<1, 0, [SDTCisVT<0, f64>]>, - [SDNPOutFlag]>; + [SDNPOutGlue]>; def PPCmtfsb0 : SDNode<"PPCISD::MTFSB0", SDTypeProfile<0, 1, [SDTCisInt<0>]>, - [SDNPInFlag, SDNPOutFlag]>; + [SDNPInGlue, SDNPOutGlue]>; def PPCmtfsb1 : SDNode<"PPCISD::MTFSB1", SDTypeProfile<0, 1, [SDTCisInt<0>]>, - [SDNPInFlag, SDNPOutFlag]>; + [SDNPInGlue, SDNPOutGlue]>; def PPCfaddrtz: SDNode<"PPCISD::FADDRTZ", SDTFPBinOp, - [SDNPInFlag, SDNPOutFlag]>; + [SDNPInGlue, SDNPOutGlue]>; def PPCmtfsf : SDNode<"PPCISD::MTFSF", SDTypeProfile<1, 3, [SDTCisVT<0, f64>, SDTCisInt<1>, SDTCisVT<2, f64>, SDTCisVT<3, f64>]>, - [SDNPInFlag]>; + [SDNPInGlue]>; def PPCfsel : SDNode<"PPCISD::FSEL", // Type constraint for fsel. @@ -105,45 +105,45 @@ // These are target-independent nodes, but have target-specific formats. def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_PPCCallSeqStart, - [SDNPHasChain, SDNPOutFlag]>; + [SDNPHasChain, SDNPOutGlue]>; def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_PPCCallSeqEnd, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; def SDT_PPCCall : SDTypeProfile<0, -1, [SDTCisInt<0>]>; def PPCcall_Darwin : SDNode<"PPCISD::CALL_Darwin", SDT_PPCCall, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag, + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>; def PPCcall_SVR4 : SDNode<"PPCISD::CALL_SVR4", SDT_PPCCall, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag, + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>; -def PPCnop : SDNode<"PPCISD::NOP", SDT_PPCnop, [SDNPInFlag, SDNPOutFlag]>; +def PPCnop : SDNode<"PPCISD::NOP", SDT_PPCnop, [SDNPInGlue, SDNPOutGlue]>; def PPCload : SDNode<"PPCISD::LOAD", SDTypeProfile<1, 1, []>, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; def PPCload_toc : SDNode<"PPCISD::LOAD_TOC", SDTypeProfile<0, 1, []>, - [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>; def PPCtoc_restore : SDNode<"PPCISD::TOC_RESTORE", SDTypeProfile<0, 0, []>, - [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>; def PPCmtctr : SDNode<"PPCISD::MTCTR", SDT_PPCCall, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; def PPCbctrl_Darwin : SDNode<"PPCISD::BCTRL_Darwin", SDTNone, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag, + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>; def PPCbctrl_SVR4 : SDNode<"PPCISD::BCTRL_SVR4", SDTNone, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag, + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>; def retflag : SDNode<"PPCISD::RET_FLAG", SDTNone, - [SDNPHasChain, SDNPOptInFlag, SDNPVariadic]>; + [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; def PPCtc_return : SDNode<"PPCISD::TC_RETURN", SDT_PPCTC_ret, - [SDNPHasChain, SDNPOptInFlag, SDNPVariadic]>; + [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; def PPCvcmp : SDNode<"PPCISD::VCMP" , SDT_PPCvcmp, []>; -def PPCvcmp_o : SDNode<"PPCISD::VCMPo", SDT_PPCvcmp, [SDNPOutFlag]>; +def PPCvcmp_o : SDNode<"PPCISD::VCMPo", SDT_PPCvcmp, [SDNPOutGlue]>; def PPCcondbranch : SDNode<"PPCISD::COND_BRANCH", SDT_PPCcondbr, - [SDNPHasChain, SDNPOptInFlag]>; + [SDNPHasChain, SDNPOptInGlue]>; def PPClbrx : SDNode<"PPCISD::LBRX", SDT_PPClbrx, [SDNPHasChain, SDNPMayLoad]>; Modified: llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td?rev=122513&r1=122512&r2=122513&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td (original) +++ llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td Thu Dec 23 12:28:41 2010 @@ -95,10 +95,10 @@ def SDTSPITOF : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f32>]>; -def SPcmpicc : SDNode<"SPISD::CMPICC", SDTIntBinOp, [SDNPOutFlag]>; -def SPcmpfcc : SDNode<"SPISD::CMPFCC", SDTSPcmpfcc, [SDNPOutFlag]>; -def SPbricc : SDNode<"SPISD::BRICC", SDTSPbrcc, [SDNPHasChain, SDNPInFlag]>; -def SPbrfcc : SDNode<"SPISD::BRFCC", SDTSPbrcc, [SDNPHasChain, SDNPInFlag]>; +def SPcmpicc : SDNode<"SPISD::CMPICC", SDTIntBinOp, [SDNPOutGlue]>; +def SPcmpfcc : SDNode<"SPISD::CMPFCC", SDTSPcmpfcc, [SDNPOutGlue]>; +def SPbricc : SDNode<"SPISD::BRICC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>; +def SPbrfcc : SDNode<"SPISD::BRFCC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>; def SPhi : SDNode<"SPISD::Hi", SDTIntUnaryOp>; def SPlo : SDNode<"SPISD::Lo", SDTIntUnaryOp>; @@ -106,8 +106,8 @@ def SPftoi : SDNode<"SPISD::FTOI", SDTSPFTOI>; def SPitof : SDNode<"SPISD::ITOF", SDTSPITOF>; -def SPselecticc : SDNode<"SPISD::SELECT_ICC", SDTSPselectcc, [SDNPInFlag]>; -def SPselectfcc : SDNode<"SPISD::SELECT_FCC", SDTSPselectcc, [SDNPInFlag]>; +def SPselecticc : SDNode<"SPISD::SELECT_ICC", SDTSPselectcc, [SDNPInGlue]>; +def SPselectfcc : SDNode<"SPISD::SELECT_FCC", SDTSPselectcc, [SDNPInGlue]>; // These are target-independent nodes, but have target-specific formats. def SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>; @@ -115,16 +115,16 @@ SDTCisVT<1, i32> ]>; def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart, - [SDNPHasChain, SDNPOutFlag]>; + [SDNPHasChain, SDNPOutGlue]>; def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPCallSeqEnd, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; def SDT_SPCall : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; def call : SDNode<"SPISD::CALL", SDT_SPCall, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; def retflag : SDNode<"SPISD::RET_FLAG", SDTNone, - [SDNPHasChain, SDNPOptInFlag]>; + [SDNPHasChain, SDNPOptInGlue]>; def getPCX : Operand { let PrintMethod = "printGetPCX"; Modified: llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td?rev=122513&r1=122512&r2=122513&view=diff ============================================================================== --- llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td (original) +++ llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td Thu Dec 23 12:28:41 2010 @@ -46,15 +46,15 @@ // SystemZ Specific Node Definitions. //===----------------------------------------------------------------------===// def SystemZretflag : SDNode<"SystemZISD::RET_FLAG", SDTNone, - [SDNPHasChain, SDNPOptInFlag]>; + [SDNPHasChain, SDNPOptInGlue]>; def SystemZcall : SDNode<"SystemZISD::CALL", SDT_SystemZCall, - [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag, SDNPVariadic]>; + [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>; def SystemZcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SystemZCallSeqStart, - [SDNPHasChain, SDNPOutFlag]>; + [SDNPHasChain, SDNPOutGlue]>; def SystemZcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SystemZCallSeqEnd, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; def SystemZcmp : SDNode<"SystemZISD::CMP", SDT_CmpTest>; def SystemZucmp : SDNode<"SystemZISD::UCMP", SDT_CmpTest>; def SystemZbrcond : SDNode<"SystemZISD::BRCOND", SDT_BrCond, Modified: llvm/trunk/lib/Target/X86/X86InstrFPStack.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFPStack.td?rev=122513&r1=122512&r2=122513&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrFPStack.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrFPStack.td Thu Dec 23 12:28:41 2010 @@ -34,12 +34,12 @@ def X86fld : SDNode<"X86ISD::FLD", SDTX86Fld, [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; def X86fst : SDNode<"X86ISD::FST", SDTX86Fst, - [SDNPHasChain, SDNPInFlag, SDNPMayStore, + [SDNPHasChain, SDNPInGlue, SDNPMayStore, SDNPMemOperand]>; def X86fild : SDNode<"X86ISD::FILD", SDTX86Fild, [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; def X86fildflag : SDNode<"X86ISD::FILD_FLAG", SDTX86Fild, - [SDNPHasChain, SDNPOutFlag, SDNPMayLoad, + [SDNPHasChain, SDNPOutGlue, SDNPMayLoad, SDNPMemOperand]>; def X86fp_to_i16mem : SDNode<"X86ISD::FP_TO_INT16_IN_MEM", SDTX86FpToIMem, [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=122513&r1=122512&r2=122513&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Thu Dec 23 12:28:41 2010 @@ -128,10 +128,10 @@ def X86setcc_c : SDNode<"X86ISD::SETCC_CARRY", SDTX86SetCC_C>; def X86cas : SDNode<"X86ISD::LCMPXCHG_DAG", SDTX86cas, - [SDNPHasChain, SDNPInFlag, SDNPOutFlag, SDNPMayStore, + [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; def X86cas8 : SDNode<"X86ISD::LCMPXCHG8_DAG", SDTX86cas8, - [SDNPHasChain, SDNPInFlag, SDNPOutFlag, SDNPMayStore, + [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; def X86AtomAdd64 : SDNode<"X86ISD::ATOMADD64_DAG", SDTX86atomicBinary, [SDNPHasChain, SDNPMayStore, @@ -155,7 +155,7 @@ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86Ret, - [SDNPHasChain, SDNPOptInFlag, SDNPVariadic]>; + [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; def X86vastart_save_xmm_regs : SDNode<"X86ISD::VASTART_SAVE_XMM_REGS", @@ -167,35 +167,35 @@ SDNPMemOperand]>; def X86callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_X86CallSeqStart, - [SDNPHasChain, SDNPOutFlag]>; + [SDNPHasChain, SDNPOutGlue]>; def X86callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_X86CallSeqEnd, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; def X86call : SDNode<"X86ISD::CALL", SDT_X86Call, - [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag, + [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>; def X86rep_stos: SDNode<"X86ISD::REP_STOS", SDTX86RepStr, - [SDNPHasChain, SDNPInFlag, SDNPOutFlag, SDNPMayStore]>; + [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore]>; def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr, - [SDNPHasChain, SDNPInFlag, SDNPOutFlag, SDNPMayStore, + [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore, SDNPMayLoad]>; def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG", SDTX86Void, - [SDNPHasChain, SDNPOutFlag, SDNPSideEffect]>; + [SDNPHasChain, SDNPOutGlue, SDNPSideEffect]>; def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>; def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP", SDTX86Wrapper>; def X86tlsaddr : SDNode<"X86ISD::TLSADDR", SDT_X86TLSADDR, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET, [SDNPHasChain]>; def X86tcret : SDNode<"X86ISD::TC_RETURN", SDT_X86TCRET, - [SDNPHasChain, SDNPOptInFlag, SDNPVariadic]>; + [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; def X86add_flag : SDNode<"X86ISD::ADD", SDTBinaryArithWithFlags, [SDNPCommutative]>; @@ -219,10 +219,10 @@ def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>; def X86WinAlloca : SDNode<"X86ISD::WIN_ALLOCA", SDTX86Void, - [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>; def X86TLSCall : SDNode<"X86ISD::TLSCALL", SDT_X86TLSCALL, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; //===----------------------------------------------------------------------===// // X86 Operand Definitions. Modified: llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td?rev=122513&r1=122512&r2=122513&view=diff ============================================================================== --- llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td (original) +++ llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td Thu Dec 23 12:28:41 2010 @@ -29,11 +29,11 @@ // Call def SDT_XCoreBranchLink : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; def XCoreBranchLink : SDNode<"XCoreISD::BL",SDT_XCoreBranchLink, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag, + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>; def XCoreRetsp : SDNode<"XCoreISD::RETSP", SDTBrind, - [SDNPHasChain, SDNPOptInFlag]>; + [SDNPHasChain, SDNPOptInGlue]>; def SDT_XCoreBR_JT : SDTypeProfile<0, 2, [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; @@ -66,9 +66,9 @@ SDTCisVT<1, i32> ]>; def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_XCoreCallSeqStart, - [SDNPHasChain, SDNPOutFlag]>; + [SDNPHasChain, SDNPOutGlue]>; def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_XCoreCallSeqEnd, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; //===----------------------------------------------------------------------===// // Instruction Pattern Stuff Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp?rev=122513&r1=122512&r2=122513&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Thu Dec 23 12:28:41 2010 @@ -732,12 +732,12 @@ Properties |= 1 << SDNPAssociative; } else if (PropList[i]->getName() == "SDNPHasChain") { Properties |= 1 << SDNPHasChain; - } else if (PropList[i]->getName() == "SDNPOutFlag") { - Properties |= 1 << SDNPOutFlag; - } else if (PropList[i]->getName() == "SDNPInFlag") { - Properties |= 1 << SDNPInFlag; - } else if (PropList[i]->getName() == "SDNPOptInFlag") { - Properties |= 1 << SDNPOptInFlag; + } else if (PropList[i]->getName() == "SDNPOutGlue") { + Properties |= 1 << SDNPOutGlue; + } else if (PropList[i]->getName() == "SDNPInGlue") { + Properties |= 1 << SDNPInGlue; + } else if (PropList[i]->getName() == "SDNPOptInGlue") { + Properties |= 1 << SDNPOptInGlue; } else if (PropList[i]->getName() == "SDNPMayStore") { Properties |= 1 << SDNPMayStore; } else if (PropList[i]->getName() == "SDNPMayLoad") { Modified: llvm/trunk/utils/TableGen/CodeGenTarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.cpp?rev=122513&r1=122512&r2=122513&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenTarget.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenTarget.cpp Thu Dec 23 12:28:41 2010 @@ -404,8 +404,8 @@ for (unsigned i = 0, e = PropList.size(); i != e; ++i) if (PropList[i]->getName() == "SDNPHasChain") { Properties |= 1 << SDNPHasChain; - } else if (PropList[i]->getName() == "SDNPOptInFlag") { - Properties |= 1 << SDNPOptInFlag; + } else if (PropList[i]->getName() == "SDNPOptInGlue") { + Properties |= 1 << SDNPOptInGlue; } else if (PropList[i]->getName() == "SDNPMayStore") { Properties |= 1 << SDNPMayStore; } else if (PropList[i]->getName() == "SDNPMayLoad") { Modified: llvm/trunk/utils/TableGen/CodeGenTarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.h?rev=122513&r1=122512&r2=122513&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenTarget.h (original) +++ llvm/trunk/utils/TableGen/CodeGenTarget.h Thu Dec 23 12:28:41 2010 @@ -35,9 +35,9 @@ SDNPCommutative, SDNPAssociative, SDNPHasChain, - SDNPOutFlag, - SDNPInFlag, - SDNPOptInFlag, + SDNPOutGlue, + SDNPInGlue, + SDNPOptInGlue, SDNPMayLoad, SDNPMayStore, SDNPSideEffect, Modified: llvm/trunk/utils/TableGen/DAGISelMatcher.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcher.cpp?rev=122513&r1=122512&r2=122513&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/DAGISelMatcher.cpp (original) +++ llvm/trunk/utils/TableGen/DAGISelMatcher.cpp Thu Dec 23 12:28:41 2010 @@ -306,7 +306,7 @@ const EmitNodeMatcherCommon *M = cast(m); return M->OpcodeName == OpcodeName && M->VTs == VTs && M->Operands == Operands && M->HasChain == HasChain && - M->HasInFlag == HasInFlag && M->HasOutFlag == HasOutFlag && + M->HasInGlue == HasInGlue && M->HasOutGlue == HasOutGlue && M->HasMemRefs == HasMemRefs && M->NumFixedArityOperands == NumFixedArityOperands; } Modified: llvm/trunk/utils/TableGen/DAGISelMatcher.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcher.h?rev=122513&r1=122512&r2=122513&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/DAGISelMatcher.h (original) +++ llvm/trunk/utils/TableGen/DAGISelMatcher.h Thu Dec 23 12:28:41 2010 @@ -955,7 +955,7 @@ std::string OpcodeName; const SmallVector VTs; const SmallVector Operands; - bool HasChain, HasInFlag, HasOutFlag, HasMemRefs; + bool HasChain, HasInGlue, HasOutGlue, 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 @@ -970,7 +970,7 @@ int numfixedarityoperands, bool isMorphNodeTo) : Matcher(isMorphNodeTo ? MorphNodeTo : EmitNode), OpcodeName(opcodeName), VTs(vts, vts+numvts), Operands(operands, operands+numops), - HasChain(hasChain), HasInFlag(hasInGlue), HasOutFlag(hasOutGlue), + HasChain(hasChain), HasInGlue(hasInGlue), HasOutGlue(hasOutGlue), HasMemRefs(hasmemrefs), NumFixedArityOperands(numfixedarityoperands) {} const std::string &getOpcodeName() const { return OpcodeName; } @@ -992,8 +992,8 @@ bool hasChain() const { return HasChain; } - bool hasInFlag() const { return HasInFlag; } - bool hasOutFlag() const { return HasOutFlag; } + bool hasInFlag() const { return HasInGlue; } + bool hasOutFlag() const { return HasOutGlue; } bool hasMemRefs() const { return HasMemRefs; } int getNumFixedArityOperands() const { return NumFixedArityOperands; } Modified: llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp?rev=122513&r1=122512&r2=122513&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp (original) +++ llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp Thu Dec 23 12:28:41 2010 @@ -365,8 +365,8 @@ Root->getOperator() == CGP.get_intrinsic_wo_chain_sdnode() || PInfo.getNumOperands() > 1 || PInfo.hasProperty(SDNPHasChain) || - PInfo.hasProperty(SDNPInFlag) || - PInfo.hasProperty(SDNPOptInFlag); + PInfo.hasProperty(SDNPInGlue) || + PInfo.hasProperty(SDNPOptInGlue); } if (NeedCheck) @@ -375,7 +375,7 @@ } // If this node has an output glue and isn't the root, remember it. - if (N->NodeHasProperty(SDNPOutFlag, CGP) && + if (N->NodeHasProperty(SDNPOutGlue, CGP) && N != Pattern.getSrcPattern()) { // TODO: This redundantly records nodes with both glues and chains. @@ -389,8 +389,8 @@ // If this node is known to have an input glue or if it *might* have an input // glue, capture it as the glue input of the pattern. - if (N->NodeHasProperty(SDNPOptInFlag, CGP) || - N->NodeHasProperty(SDNPInFlag, CGP)) + if (N->NodeHasProperty(SDNPOptInGlue, CGP) || + N->NodeHasProperty(SDNPInGlue, CGP)) AddMatcher(new CaptureGlueInputMatcher()); for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) { @@ -659,12 +659,12 @@ bool TreeHasInGlue = false, TreeHasOutGlue = false; if (isRoot) { const TreePatternNode *SrcPat = Pattern.getSrcPattern(); - TreeHasInGlue = SrcPat->TreeHasProperty(SDNPOptInFlag, CGP) || - SrcPat->TreeHasProperty(SDNPInFlag, CGP); + TreeHasInGlue = SrcPat->TreeHasProperty(SDNPOptInGlue, CGP) || + SrcPat->TreeHasProperty(SDNPInGlue, 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. - TreeHasOutGlue = SrcPat->TreeHasProperty(SDNPOutFlag, CGP); + TreeHasOutGlue = SrcPat->TreeHasProperty(SDNPOutGlue, CGP); } // NumResults - This is the number of results produced by the instruction in Modified: llvm/trunk/utils/TableGen/DAGISelMatcherOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcherOpt.cpp?rev=122513&r1=122512&r2=122513&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/DAGISelMatcherOpt.cpp (original) +++ llvm/trunk/utils/TableGen/DAGISelMatcherOpt.cpp Thu Dec 23 12:28:41 2010 @@ -116,7 +116,7 @@ // because the code in the pattern generator doesn't handle it right. We // do it anyway for thoroughness. if (!EN->hasOutFlag() && - Pattern.getSrcPattern()->NodeHasProperty(SDNPOutFlag, CGP)) + Pattern.getSrcPattern()->NodeHasProperty(SDNPOutGlue, CGP)) ResultsMatch = false; From resistor at mac.com Thu Dec 23 14:57:35 2010 From: resistor at mac.com (Owen Anderson) Date: Thu, 23 Dec 2010 20:57:35 -0000 Subject: [llvm-commits] [llvm] r122516 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <20101223205735.3796C2A6C12C@llvm.org> Author: resistor Date: Thu Dec 23 14:57:35 2010 New Revision: 122516 URL: http://llvm.org/viewvc/llvm-project?rev=122516&view=rev Log: It is possible for SimplifyCFG to cause PHI nodes to become redundant too late in the optimization pipeline to be caught by instcombine, and it's not feasible to catch them in SimplifyCFG because the use-lists are in an inconsistent state at the point where it could know that it need to simplify them. Instead, have CodeGenPrepare look for trivially redundant PHIs as part of its general cleanup effort. Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=122516&r1=122515&r2=122516&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Thu Dec 23 14:57:35 2010 @@ -22,6 +22,7 @@ #include "llvm/Instructions.h" #include "llvm/IntrinsicInst.h" #include "llvm/Pass.h" +#include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/ProfileInfo.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetLowering.h" @@ -959,7 +960,15 @@ for (BasicBlock::iterator BBI = BB.begin(), E = BB.end(); BBI != E; ) { Instruction *I = BBI++; - if (CastInst *CI = dyn_cast(I)) { + if (PHINode *P = dyn_cast(I)) { + // It is possible for very late stage optimizations (such as SimplifyCFG) + // to introduce PHI nodes too late to be cleaned up. If we detect such a + // trivial PHI, go ahead and zap it here. + if (Value *V = SimplifyInstruction(P)) { + P->replaceAllUsesWith(V); + P->eraseFromParent(); + } + } else if (CastInst *CI = dyn_cast(I)) { // If the source of the cast is a constant, then this should have // already been constant folded. The only reason NOT to constant fold // it is if something (e.g. LSR) was careful to place the constant From edwintorok at gmail.com Thu Dec 23 15:22:09 2010 From: edwintorok at gmail.com (Torok Edwin) Date: Thu, 23 Dec 2010 21:22:09 -0000 Subject: [llvm-commits] [llvm] r122517 - /llvm/trunk/test/Bindings/Ocaml/ext_exc.ml Message-ID: <20101223212209.9640F2A6C12C@llvm.org> Author: edwin Date: Thu Dec 23 15:22:09 2010 New Revision: 122517 URL: http://llvm.org/viewvc/llvm-project?rev=122517&view=rev Log: XFAIL vg_leak the new test as the rest. Modified: llvm/trunk/test/Bindings/Ocaml/ext_exc.ml Modified: llvm/trunk/test/Bindings/Ocaml/ext_exc.ml URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bindings/Ocaml/ext_exc.ml?rev=122517&r1=122516&r2=122517&view=diff ============================================================================== --- llvm/trunk/test/Bindings/Ocaml/ext_exc.ml (original) +++ llvm/trunk/test/Bindings/Ocaml/ext_exc.ml Thu Dec 23 15:22:09 2010 @@ -1,5 +1,6 @@ (* RUN: %ocamlopt -warn-error A llvm.cmxa llvm_bitreader.cmxa llvm_executionengine.cmxa %s -o %t * RUN: %t Author: ofv Date: Thu Dec 23 15:27:22 2010 New Revision: 122518 URL: http://llvm.org/viewvc/llvm-project?rev=122518&view=rev Log: Do not re-test for the existence of pthread.h. It was causing problems on the MinGW build. See PR8849. Modified: llvm/trunk/examples/CMakeLists.txt Modified: llvm/trunk/examples/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/CMakeLists.txt?rev=122518&r1=122517&r2=122518&view=diff ============================================================================== --- llvm/trunk/examples/CMakeLists.txt (original) +++ llvm/trunk/examples/CMakeLists.txt Thu Dec 23 15:27:22 2010 @@ -8,9 +8,6 @@ add_subdirectory(ExceptionDemo) endif() -include(CheckIncludeFile) -check_include_file(pthread.h HAVE_PTHREAD_H) - if( HAVE_PTHREAD_H ) add_subdirectory(ParallelJIT) endif( HAVE_PTHREAD_H ) From bob.wilson at apple.com Thu Dec 23 16:45:49 2010 From: bob.wilson at apple.com (Bob Wilson) Date: Thu, 23 Dec 2010 22:45:49 -0000 Subject: [llvm-commits] [llvm] r122521 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp test/CodeGen/ARM/fpcmp-opt.ll Message-ID: <20101223224550.0005F2A6C12C@llvm.org> Author: bwilson Date: Thu Dec 23 16:45:49 2010 New Revision: 122521 URL: http://llvm.org/viewvc/llvm-project?rev=122521&view=rev Log: Radar 8803471: Fix expansion of ARM BCCi64 pseudo instructions. If the basic block containing the BCCi64 (or BCCZi64) instruction ends with an unconditional branch, that branch needs to be deleted before appending the expansion of the BCCi64 to the end of the block. Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/test/CodeGen/ARM/fpcmp-opt.ll Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=122521&r1=122520&r2=122521&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Thu Dec 23 16:45:49 2010 @@ -4433,6 +4433,9 @@ case ARM::BCCi64: case ARM::BCCZi64: { + // If there is an unconditional branch to the other successor, remove it. + BB->erase(llvm::next(MachineBasicBlock::iterator(MI)), BB->end()); + // Compare both parts that make up the double comparison separately for // equality. bool RHSisZero = MI->getOpcode() == ARM::BCCZi64; Modified: llvm/trunk/test/CodeGen/ARM/fpcmp-opt.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/fpcmp-opt.ll?rev=122521&r1=122520&r2=122521&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/fpcmp-opt.ll (original) +++ llvm/trunk/test/CodeGen/ARM/fpcmp-opt.ll Thu Dec 23 16:45:49 2010 @@ -38,6 +38,7 @@ ; FINITE: t2: ; FINITE-NOT: vldr ; FINITE: ldrd r0, [r0] +; FINITE-NOT: b LBB ; FINITE: cmp r0, #0 ; FINITE: cmpeq r1, #0 ; FINITE-NOT: vcmpe.f32 From grosbach at apple.com Thu Dec 23 17:19:54 2010 From: grosbach at apple.com (Jim Grosbach) Date: Thu, 23 Dec 2010 23:19:54 -0000 Subject: [llvm-commits] [llvm] r122523 - /llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmLexer.cpp Message-ID: <20101223231954.A46042A6C12C@llvm.org> Author: grosbach Date: Thu Dec 23 17:19:54 2010 New Revision: 122523 URL: http://llvm.org/viewvc/llvm-project?rev=122523&view=rev Log: Recognize a few more documented register name aliases for ARM in the asm lexer. 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=122523&r1=122522&r2=122523&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmLexer.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmLexer.cpp Thu Dec 23 17:19:54 2010 @@ -121,6 +121,24 @@ StringRef lowerRef(lowerCase); unsigned regID = MatchRegisterName(lowerRef); + // Check for register aliases. + // r13 -> sp + // r14 -> lr + // r15 -> pc + // ip -> r12 + // FIXME: Some assemblers support lots of others. Do we want them all? + if (!regID) { + if (lowerCase.size() == 3 && lowerCase[0] == 'r' + && lowerCase[1] == '1') { + switch (lowerCase[2]) { + default: break; + case '3': regID = ARM::SP; + case '4': regID = ARM::LR; + case '5': regID = ARM::PC; + } + } else if (lowerCase == "ip") + regID = ARM::R12; + } if (regID) { return AsmToken(AsmToken::Register, From grosbach at apple.com Thu Dec 23 17:20:13 2010 From: grosbach at apple.com (Jim Grosbach) Date: Thu, 23 Dec 2010 23:20:13 -0000 Subject: [llvm-commits] [llvm] r122524 - /llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Message-ID: <20101223232013.E87C52A6C12C@llvm.org> Author: grosbach Date: Thu Dec 23 17:20:13 2010 New Revision: 122524 URL: http://llvm.org/viewvc/llvm-project?rev=122524&view=rev Log: Remove dead patterns. Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=122524&r1=122523&r2=122524&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Thu Dec 23 17:20:13 2010 @@ -412,32 +412,6 @@ return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue()); }]>; -def so_imm2part_1 : SDNodeXFormgetZExtValue()); - return CurDAG->getTargetConstant(V, MVT::i32); -}]>; - -def so_imm2part_2 : SDNodeXFormgetZExtValue()); - return CurDAG->getTargetConstant(V, MVT::i32); -}]>; - -def so_neg_imm2part : Operand, PatLeaf<(imm), [{ - return ARM_AM::isSOImmTwoPartVal(-(int)N->getZExtValue()); - }]> { - let PrintMethod = "printSOImm2PartOperand"; -} - -def so_neg_imm2part_1 : SDNodeXFormgetZExtValue()); - return CurDAG->getTargetConstant(V, MVT::i32); -}]>; - -def so_neg_imm2part_2 : SDNodeXFormgetZExtValue()); - return CurDAG->getTargetConstant(V, MVT::i32); -}]>; - /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31]. def imm0_31 : Operand, PatLeaf<(imm), [{ return (int32_t)N->getZExtValue() < 32; From aggarwa4 at illinois.edu Thu Dec 23 17:32:09 2010 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Thu, 23 Dec 2010 23:32:09 -0000 Subject: [llvm-commits] [poolalloc] r122526 - in /poolalloc/trunk: include/dsa/DSCallGraph.h lib/DSA/DSCallGraph.cpp lib/DSA/DSGraph.cpp lib/PoolAllocate/PoolAllocate.cpp test/pa/clone/Incomplete.ll Message-ID: <20101223233209.BAEB72A6C12C@llvm.org> Author: aggarwa4 Date: Thu Dec 23 17:32:09 2010 New Revision: 122526 URL: http://llvm.org/viewvc/llvm-project?rev=122526&view=rev Log: Make sure that poolallocation does not pass pool arguments to functions that can be called from an unresolved call site. Upgrade DSCallgraph to provide this information. Added: poolalloc/trunk/test/pa/clone/Incomplete.ll Modified: poolalloc/trunk/include/dsa/DSCallGraph.h poolalloc/trunk/lib/DSA/DSCallGraph.cpp poolalloc/trunk/lib/DSA/DSGraph.cpp poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Modified: poolalloc/trunk/include/dsa/DSCallGraph.h URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSCallGraph.h?rev=122526&r1=122525&r2=122526&view=diff ============================================================================== --- poolalloc/trunk/include/dsa/DSCallGraph.h (original) +++ poolalloc/trunk/include/dsa/DSCallGraph.h Thu Dec 23 17:32:09 2010 @@ -46,6 +46,10 @@ // Functions we know about that aren't called svset knownRoots; + + // Functions that might be called from an incomplete + // unresolved call site. + svset IncompleteCalleeSet; svset completeCS; @@ -152,6 +156,10 @@ return ii->second.size(); } + bool called_from_incomplete_site(const llvm::Function *F) const { + return !(IncompleteCalleeSet.find(F) + == IncompleteCalleeSet.end()); + } void callee_mark_complete(llvm::CallSite CS) { completeCS.insert(CS); } @@ -175,6 +183,8 @@ void buildSCCs(); void buildRoots(); + + void buildIncompleteCalleeSet(svset callees); void dump(); Modified: poolalloc/trunk/lib/DSA/DSCallGraph.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DSCallGraph.cpp?rev=122526&r1=122525&r2=122526&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/DSCallGraph.cpp (original) +++ poolalloc/trunk/lib/DSA/DSCallGraph.cpp Thu Dec 23 17:32:09 2010 @@ -170,6 +170,10 @@ std::inserter(knownRoots, knownRoots.begin())); } +void DSCallGraph::buildIncompleteCalleeSet(svset callees) { + IncompleteCalleeSet.insert(callees.begin(), callees.end()); +} + template void printNameOrPtr(T& Out, const llvm::Function* F) { if (F->hasName()) Modified: poolalloc/trunk/lib/DSA/DSGraph.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DSGraph.cpp?rev=122526&r1=122525&r2=122526&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/DSGraph.cpp (original) +++ poolalloc/trunk/lib/DSA/DSGraph.cpp Thu Dec 23 17:32:09 2010 @@ -1666,7 +1666,8 @@ } } } -void DSGraph::buildCompleteCallGraph(DSCallGraph& DCG, std::vector& GlobalFunctionList, bool filter) const { +void DSGraph::buildCompleteCallGraph(DSCallGraph& DCG, + std::vector& GlobalFunctionList, bool filter) const { // // Get the list of unresolved call sites. // @@ -1702,6 +1703,9 @@ else ++NumFiltered; } - } + } } + svset callees; + callees.insert(GlobalFunctionList.begin(), GlobalFunctionList.end()); + DCG.buildIncompleteCalleeSet(callees); } Modified: poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp?rev=122526&r1=122525&r2=122526&view=diff ============================================================================== --- poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp (original) +++ poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Thu Dec 23 17:32:09 2010 @@ -701,9 +701,21 @@ Functions.push_back (*sccii); } } - if(!externFunctionFound) - FindFunctionPoolArgs (Functions); - else { + bool doNotPassPools = externFunctionFound; + // go through the list of functions to check if any is external + // or callable from an incomplete call site. Then no pool args + // are needed; else find pool args. + if(!doNotPassPools){ + for (unsigned index = 0; index < Functions.size(); ++index) { + const Function * F = Functions[index]; + if (callgraph.called_from_incomplete_site(F)){ + doNotPassPools = true; + break; + } + } + } + + if(doNotPassPools) { // 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 @@ -718,47 +730,12 @@ } FunctionInfo.insert(std::make_pair(F, FuncInfo(*F))).first->second; } + } else { + FindFunctionPoolArgs (Functions); } - } } - /* - EquivalenceClasses & GlobalECs = Graphs->getGlobalECs(); - EquivalenceClasses::iterator EQSI = GlobalECs.begin(); - EquivalenceClasses::iterator EQSE = GlobalECs.end(); - for (;EQSI != EQSE; ++EQSI) { - // - // If this element is not a leader, then skip it. - // - if (!EQSI->isLeader()) continue; - - // - // Iterate through all members of this equivalence class, looking for - // functions. Record all of those functions which need to be processed. - // - std::vector Functions; - EquivalenceClasses::member_iterator MI; - for (MI=GlobalECs.member_begin(EQSI); MI != GlobalECs.member_end(); ++MI) { - if (const Function* F = dyn_cast(*MI)) { - // - // If the function has no body, then it has no DSGraph. - // - // FIXME: I don't believe this is correct; the stdlib pass can assign - // DSGraphs to C standard library functions. - // - if (!(F->isDeclaration())) - Functions.push_back (F); - } - } - - // - // Find the pool arguments for all of the functions in the equivalence - // class and construct the FuncInfo structure for each one. - // - FindFunctionPoolArgs (Functions); - }*/ - // // Make sure every function has a FuncInfo structure. // Added: poolalloc/trunk/test/pa/clone/Incomplete.ll URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/pa/clone/Incomplete.ll?rev=122526&view=auto ============================================================================== --- poolalloc/trunk/test/pa/clone/Incomplete.ll (added) +++ poolalloc/trunk/test/pa/clone/Incomplete.ll Thu Dec 23 17:32:09 2010 @@ -0,0 +1,65 @@ +;This test checks that functions callable from incomplete call sites +;are not cloned. +;RUN: paopt %s -paheur-AllButUnreachableFromMemory -poolalloc -o %t.bc |& grep "Pool allocating.*nodes!" +;RUN: llvm-dis %t.bc -o %t.ll +;Make sure address taken functions A and C are not cloned +;RUN: cat %t.ll | grep -v "A_clone" +;RUN: cat %t.ll | grep -v "C_clone" +;But ensure that B is cloned. +;RUN: cat %t.ll | grep "B_clone" + +; ModuleID = 'fptr.o' +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +define void @A(void (i8*)** %f) nounwind { +entry: + %f_addr = alloca void (i8*)** ; [#uses=1] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store void (i8*)** %f, void (i8*)*** %f_addr + br label %return + +return: ; preds = %entry + ret void +} + +define void @B(void (i8*)** %f) nounwind { +entry: + %f_addr = alloca void (i8*)** ; [#uses=1] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store void (i8*)** %f, void (i8*)*** %f_addr + br label %return + +return: ; preds = %entry + ret void +} + +define void @C(void (i8*)** %f) nounwind { +entry: + %f_addr = alloca void (i8*)** ; [#uses=1] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store void (i8*)** %f, void (i8*)*** %f_addr + br label %return + +return: ; preds = %entry + ret void +} + +define i32 @main() nounwind { +entry: + %retval = alloca i32 ; [#uses=1] + %F = alloca void (i8*)* ; [#uses=4] + %F1 = alloca void (i8*)* ; [#uses=1] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store void (i8*)* bitcast (void (void (i8*)**)* @A to void (i8*)*), void (i8*)** %F, align 8 + store void (i8*)* bitcast (void (void (i8*)**)* @C to void (i8*)*), void (i8*)** %F1, align 8 + %0 = load void (i8*)** %F, align 8 ; [#uses=1] + %F2 = bitcast void (i8*)** %F to i8* ; [#uses=1] + call void %0(i8* %F2) nounwind + call void @B(void (i8*)** %F) nounwind + br label %return + +return: ; preds = %entry + %retval3 = load i32* %retval ; [#uses=1] + ret i32 %retval3 +} From clattner at apple.com Thu Dec 23 17:38:01 2010 From: clattner at apple.com (Chris Lattner) Date: Thu, 23 Dec 2010 15:38:01 -0800 Subject: [llvm-commits] [llvm] r122523 - /llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmLexer.cpp In-Reply-To: <20101223231954.A46042A6C12C@llvm.org> References: <20101223231954.A46042A6C12C@llvm.org> Message-ID: On Dec 23, 2010, at 3:19 PM, Jim Grosbach wrote: > Author: grosbach > Date: Thu Dec 23 17:19:54 2010 > New Revision: 122523 > > URL: http://llvm.org/viewvc/llvm-project?rev=122523&view=rev > Log: > Recognize a few more documented register name aliases for ARM in the asm lexer. How about using StringSwitch? :) -Chris > > 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=122523&r1=122522&r2=122523&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmLexer.cpp (original) > +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmLexer.cpp Thu Dec 23 17:19:54 2010 > @@ -121,6 +121,24 @@ > StringRef lowerRef(lowerCase); > > unsigned regID = MatchRegisterName(lowerRef); > + // Check for register aliases. > + // r13 -> sp > + // r14 -> lr > + // r15 -> pc > + // ip -> r12 > + // FIXME: Some assemblers support lots of others. Do we want them all? > + if (!regID) { > + if (lowerCase.size() == 3 && lowerCase[0] == 'r' > + && lowerCase[1] == '1') { > + switch (lowerCase[2]) { > + default: break; > + case '3': regID = ARM::SP; > + case '4': regID = ARM::LR; > + case '5': regID = ARM::PC; > + } > + } else if (lowerCase == "ip") > + regID = ARM::R12; > + } > > if (regID) { > return AsmToken(AsmToken::Register, > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Thu Dec 23 17:54:17 2010 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 23 Dec 2010 23:54:17 -0000 Subject: [llvm-commits] [llvm] r122528 - /llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Message-ID: <20101223235417.A82F92A6C12C@llvm.org> Author: evancheng Date: Thu Dec 23 17:54:17 2010 New Revision: 122528 URL: http://llvm.org/viewvc/llvm-project?rev=122528&view=rev Log: Code clean up. No functionality change. Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp?rev=122528&r1=122527&r2=122528&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Thu Dec 23 17:54:17 2010 @@ -492,70 +492,69 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const { const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo(); + bool reseveCallFrame = TFI->hasReservedCallFrame(MF); + int Opcode = I->getOpcode(); + bool isDestroy = Opcode == getCallFrameDestroyOpcode(); + DebugLoc DL = I->getDebugLoc(); + uint64_t Amount = !reseveCallFrame ? I->getOperand(0).getImm() : 0; + uint64_t CalleeAmt = isDestroy ? I->getOperand(1).getImm() : 0; + I = MBB.erase(I); - if (!TFI->hasReservedCallFrame(MF)) { + if (!reseveCallFrame) { // If the stack pointer can be changed after prologue, turn the // adjcallstackup instruction into a 'sub ESP, ' and the // adjcallstackdown instruction into 'add ESP, ' // TODO: consider using push / pop instead of sub + store / add - MachineInstr *Old = I; - uint64_t Amount = Old->getOperand(0).getImm(); - if (Amount != 0) { - // We need to keep the stack aligned properly. To do this, we round the - // amount of space needed for the outgoing arguments up to the next - // alignment boundary. - Amount = (Amount + StackAlign - 1) / StackAlign * StackAlign; - - MachineInstr *New = 0; - if (Old->getOpcode() == getCallFrameSetupOpcode()) { - New = BuildMI(MF, Old->getDebugLoc(), - TII.get(getSUBriOpcode(Is64Bit, Amount)), - StackPtr) - .addReg(StackPtr) - .addImm(Amount); - } else { - assert(Old->getOpcode() == getCallFrameDestroyOpcode()); - - // Factor out the amount the callee already popped. - uint64_t CalleeAmt = Old->getOperand(1).getImm(); - Amount -= CalleeAmt; - - if (Amount) { - unsigned Opc = getADDriOpcode(Is64Bit, Amount); - New = BuildMI(MF, Old->getDebugLoc(), TII.get(Opc), StackPtr) - .addReg(StackPtr) - .addImm(Amount); - } - } + if (Amount == 0) + return; - if (New) { - // The EFLAGS implicit def is dead. - New->getOperand(3).setIsDead(); + // We need to keep the stack aligned properly. To do this, we round the + // amount of space needed for the outgoing arguments up to the next + // alignment boundary. + Amount = (Amount + StackAlign - 1) / StackAlign * StackAlign; + + MachineInstr *New = 0; + if (Opcode == getCallFrameSetupOpcode()) { + New = BuildMI(MF, DL, TII.get(getSUBriOpcode(Is64Bit, Amount)), + StackPtr) + .addReg(StackPtr) + .addImm(Amount); + } else { + assert(Opcode == getCallFrameDestroyOpcode()); - // Replace the pseudo instruction with a new instruction. - MBB.insert(I, New); + // Factor out the amount the callee already popped. + Amount -= CalleeAmt; + + if (Amount) { + unsigned Opc = getADDriOpcode(Is64Bit, Amount); + New = BuildMI(MF, DL, TII.get(Opc), StackPtr) + .addReg(StackPtr).addImm(Amount); } } - } else if (I->getOpcode() == getCallFrameDestroyOpcode()) { - // If we are performing frame pointer elimination and if the callee pops - // something off the stack pointer, add it back. We do this until we have - // more advanced stack pointer tracking ability. - if (uint64_t CalleeAmt = I->getOperand(1).getImm()) { - unsigned Opc = getSUBriOpcode(Is64Bit, CalleeAmt); - MachineInstr *Old = I; - MachineInstr *New = - BuildMI(MF, Old->getDebugLoc(), TII.get(Opc), - StackPtr) - .addReg(StackPtr) - .addImm(CalleeAmt); + if (New) { // The EFLAGS implicit def is dead. New->getOperand(3).setIsDead(); + + // Replace the pseudo instruction with a new instruction. MBB.insert(I, New); } + + return; } - MBB.erase(I); + if (Opcode == getCallFrameDestroyOpcode() && CalleeAmt) { + // If we are performing frame pointer elimination and if the callee pops + // something off the stack pointer, add it back. We do this until we have + // more advanced stack pointer tracking ability. + unsigned Opc = getSUBriOpcode(Is64Bit, CalleeAmt); + MachineInstr *New = BuildMI(MF, DL, TII.get(Opc), StackPtr) + .addReg(StackPtr).addImm(CalleeAmt); + + // The EFLAGS implicit def is dead. + New->getOperand(3).setIsDead(); + MBB.insert(I, New); + } } void From resistor at mac.com Thu Dec 23 17:56:25 2010 From: resistor at mac.com (Owen Anderson) Date: Thu, 23 Dec 2010 23:56:25 -0000 Subject: [llvm-commits] [llvm] r122529 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineShifts.cpp test/Transforms/InstCombine/shift.ll Message-ID: <20101223235625.16FA02A6C12C@llvm.org> Author: resistor Date: Thu Dec 23 17:56:24 2010 New Revision: 122529 URL: http://llvm.org/viewvc/llvm-project?rev=122529&view=rev Log: When determining if we can fold (x >> C1) << C2, the bits that we need to verify are zero are not the low bits of x, but the bits that WILL be the low bits after the operation completes. Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp llvm/trunk/test/Transforms/InstCombine/shift.ll Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp?rev=122529&r1=122528&r2=122529&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp Thu Dec 23 17:56:24 2010 @@ -168,8 +168,9 @@ // We can always turn lshr(c1)+shl(c2) -> lshr(c3)+and(c4), but it isn't // profitable unless we know the and'd out bits are already zero. if (CI->getZExtValue() > NumBits) { + unsigned LowBits = CI->getZExtValue() - NumBits; if (MaskedValueIsZero(I->getOperand(0), - APInt::getLowBitsSet(TypeWidth, NumBits))) + APInt::getLowBitsSet(TypeWidth, NumBits) << LowBits)) return true; } Modified: llvm/trunk/test/Transforms/InstCombine/shift.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/shift.ll?rev=122529&r1=122528&r2=122529&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/shift.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/shift.ll Thu Dec 23 17:56:24 2010 @@ -452,3 +452,22 @@ ; CHECK-NEXT: ret i32 } +; +; CHECK: @test39 +define i8 @test39(i32 %a0) { +entry: + %tmp4 = trunc i32 %a0 to i8 +; CHECK: and i8 %tmp49, 64 + %tmp5 = shl i8 %tmp4, 5 + %tmp48 = and i8 %tmp5, 32 + %tmp49 = lshr i8 %tmp48, 5 + %tmp50 = mul i8 %tmp49, 64 + %tmp51 = xor i8 %tmp50, %tmp5 +; CHECK: and i8 %0, 16 + %tmp52 = and i8 %tmp51, -128 + %tmp53 = lshr i8 %tmp52, 7 + %tmp54 = mul i8 %tmp53, 16 + %tmp55 = xor i8 %tmp54, %tmp51 +; CHECK: ret i8 %tmp551 + ret i8 %tmp55 +} From grosbach at apple.com Thu Dec 23 18:03:39 2010 From: grosbach at apple.com (Jim Grosbach) Date: Fri, 24 Dec 2010 00:03:39 -0000 Subject: [llvm-commits] [llvm] r122530 - /llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmLexer.cpp Message-ID: <20101224000339.68B5B2A6C12C@llvm.org> Author: grosbach Date: Thu Dec 23 18:03:39 2010 New Revision: 122530 URL: http://llvm.org/viewvc/llvm-project?rev=122530&view=rev Log: Use a StringSwitch<> instead of a manually constructed string matcher. 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=122530&r1=122529&r2=122530&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmLexer.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmLexer.cpp Thu Dec 23 18:03:39 2010 @@ -13,6 +13,7 @@ #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCParser/MCAsmLexer.h" @@ -128,16 +129,12 @@ // ip -> r12 // FIXME: Some assemblers support lots of others. Do we want them all? if (!regID) { - if (lowerCase.size() == 3 && lowerCase[0] == 'r' - && lowerCase[1] == '1') { - switch (lowerCase[2]) { - default: break; - case '3': regID = ARM::SP; - case '4': regID = ARM::LR; - case '5': regID = ARM::PC; - } - } else if (lowerCase == "ip") - regID = ARM::R12; + regID = StringSwitch(lowerCase) + .Case("r13", ARM::SP) + .Case("r14", ARM::LR) + .Case("r15", ARM::PC) + .Case("ip", ARM::R12) + .Default(0); } if (regID) { From grosbach at apple.com Thu Dec 23 18:07:01 2010 From: grosbach at apple.com (Jim Grosbach) Date: Thu, 23 Dec 2010 16:07:01 -0800 Subject: [llvm-commits] [llvm] r122523 - /llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmLexer.cpp In-Reply-To: References: <20101223231954.A46042A6C12C@llvm.org> Message-ID: <10D35D37-F1D1-4E3E-9C92-432AAAD324C0@apple.com> On Dec 23, 2010, at 3:38 PM, Chris Lattner wrote: > > On Dec 23, 2010, at 3:19 PM, Jim Grosbach wrote: > >> Author: grosbach >> Date: Thu Dec 23 17:19:54 2010 >> New Revision: 122523 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=122523&view=rev >> Log: >> Recognize a few more documented register name aliases for ARM in the asm lexer. > > How about using StringSwitch? :) > I had completely forgotten about StringSwitch. Thanks! done in r122530. -Jim >> >> 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=122523&r1=122522&r2=122523&view=diff >> ============================================================================== >> --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmLexer.cpp (original) >> +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmLexer.cpp Thu Dec 23 17:19:54 2010 >> @@ -121,6 +121,24 @@ >> StringRef lowerRef(lowerCase); >> >> unsigned regID = MatchRegisterName(lowerRef); >> + // Check for register aliases. >> + // r13 -> sp >> + // r14 -> lr >> + // r15 -> pc >> + // ip -> r12 >> + // FIXME: Some assemblers support lots of others. Do we want them all? >> + if (!regID) { >> + if (lowerCase.size() == 3 && lowerCase[0] == 'r' >> + && lowerCase[1] == '1') { >> + switch (lowerCase[2]) { >> + default: break; >> + case '3': regID = ARM::SP; >> + case '4': regID = ARM::LR; >> + case '5': regID = ARM::PC; >> + } >> + } else if (lowerCase == "ip") >> + regID = ARM::R12; >> + } >> >> if (regID) { >> return AsmToken(AsmToken::Register, >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From enderby at apple.com Thu Dec 23 18:12:02 2010 From: enderby at apple.com (Kevin Enderby) Date: Fri, 24 Dec 2010 00:12:02 -0000 Subject: [llvm-commits] [llvm] r122531 - in /llvm/trunk: lib/MC/MCParser/AsmParser.cpp test/MC/AsmParser/full_line_comment.s Message-ID: <20101224001202.B379F2A6C12C@llvm.org> Author: enderby Date: Thu Dec 23 18:12:02 2010 New Revision: 122531 URL: http://llvm.org/viewvc/llvm-project?rev=122531&view=rev Log: In llvm-mc parse a Hash token as a full line comment. Allows handling of preprocessed .s files and matches darwin gas. rdar://8798690 Also fix a comment on the next line of AsmParser.cpp after this new code. Added: llvm/trunk/test/MC/AsmParser/full_line_comment.s Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=122531&r1=122530&r2=122531&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original) +++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Thu Dec 23 18:12:02 2010 @@ -831,12 +831,17 @@ return false; } - // Statements always start with an identifier. + // Statements always start with an identifier or are a full line comment. AsmToken ID = getTok(); SMLoc IDLoc = ID.getLoc(); StringRef IDVal; int64_t LocalLabelVal = -1; - // GUESS allow an integer followed by a ':' as a directional local label + // A full line comment is a '#' as the first token. + if (Lexer.is(AsmToken::Hash)) { + EatToEndOfStatement(); + return false; + } + // Allow an integer followed by a ':' as a directional local label. if (Lexer.is(AsmToken::Integer)) { LocalLabelVal = getTok().getIntVal(); if (LocalLabelVal < 0) { Added: llvm/trunk/test/MC/AsmParser/full_line_comment.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/full_line_comment.s?rev=122531&view=auto ============================================================================== --- llvm/trunk/test/MC/AsmParser/full_line_comment.s (added) +++ llvm/trunk/test/MC/AsmParser/full_line_comment.s Thu Dec 23 18:12:02 2010 @@ -0,0 +1,8 @@ +// RUN: llvm-mc -triple arm-apple-darwin10 %s | FileCheck %s +# this is a full line comment starting at column 1 + # this starting at column 2 + + .data +// CHECK: .long 0 +.long 0 +# .long 1 this line is commented out From zwarich at apple.com Thu Dec 23 21:09:36 2010 From: zwarich at apple.com (Cameron Zwarich) Date: Fri, 24 Dec 2010 03:09:36 -0000 Subject: [llvm-commits] [llvm] r122537 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Message-ID: <20101224030936.919142A6C12C@llvm.org> Author: zwarich Date: Thu Dec 23 21:09:36 2010 New Revision: 122537 URL: http://llvm.org/viewvc/llvm-project?rev=122537&view=rev Log: Simplify a check for implicit defs and remove a FIXME. 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=122537&r1=122536&r2=122537&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Thu Dec 23 21:09:36 2010 @@ -189,20 +189,18 @@ SmallPtrSet MBBsInsertedInto; for (unsigned i = 1; i < PHI->getNumOperands(); i += 2) { MachineOperand& SrcMO = PHI->getOperand(i); + + // If a source is defined by an implicit def, there is no need to insert a + // copy in the predecessor. + if (SrcMO.isUndef()) + continue; + 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 From atrick at apple.com Thu Dec 23 22:28:06 2010 From: atrick at apple.com (Andrew Trick) Date: Fri, 24 Dec 2010 04:28:06 -0000 Subject: [llvm-commits] [llvm] r122539 - in /llvm/trunk: include/llvm/CodeGen/ include/llvm/Target/ lib/CodeGen/ lib/CodeGen/SelectionDAG/ lib/Target/ lib/Target/ARM/ lib/Target/CellSPU/ lib/Target/PowerPC/ Message-ID: <20101224042806.AA0C32A6C12C@llvm.org> Author: atrick Date: Thu Dec 23 22:28:06 2010 New Revision: 122539 URL: http://llvm.org/viewvc/llvm-project?rev=122539&view=rev Log: whitespace Modified: llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h llvm/trunk/include/llvm/Target/TargetInstrInfo.h llvm/trunk/include/llvm/Target/TargetInstrItineraries.h llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp llvm/trunk/lib/Target/ARM/ARMSubtarget.h llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.h llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h llvm/trunk/lib/Target/TargetInstrInfo.cpp Modified: llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h?rev=122539&r1=122538&r2=122539&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h (original) +++ llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h Thu Dec 23 22:28:06 2010 @@ -20,25 +20,25 @@ namespace llvm { class LatencyPriorityQueue; - + /// Sorting functions for the Available queue. struct latency_sort : public std::binary_function { LatencyPriorityQueue *PQ; explicit latency_sort(LatencyPriorityQueue *pq) : PQ(pq) {} - + bool operator()(const SUnit* left, const SUnit* right) const; }; class LatencyPriorityQueue : public SchedulingPriorityQueue { // SUnits - The SUnits for the current graph. std::vector *SUnits; - + /// NumNodesSolelyBlocking - This vector contains, for every node in the /// Queue, the number of nodes that the node is the sole unscheduled /// predecessor for. This is used as a tie-breaker heuristic for better /// mobility. std::vector NumNodesSolelyBlocking; - + /// Queue - The queue. std::vector Queue; latency_sort Picker; @@ -62,21 +62,21 @@ void releaseState() { SUnits = 0; } - + unsigned getLatency(unsigned NodeNum) const { assert(NodeNum < (*SUnits).size()); return (*SUnits)[NodeNum].getHeight(); } - + unsigned getNumSolelyBlockNodes(unsigned NodeNum) const { assert(NodeNum < NumNodesSolelyBlocking.size()); return NumNodesSolelyBlocking[NodeNum]; } - + bool empty() const { return Queue.empty(); } - + virtual void push(SUnit *U); - + virtual SUnit *pop(); virtual void remove(SUnit *SU); Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=122539&r1=122538&r2=122539&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Thu Dec 23 22:28:06 2010 @@ -232,8 +232,8 @@ public: SUnit *OrigNode; // If not this, the node from which // this node was cloned. - - // Preds/Succs - The SUnits before/after us in the graph. + + // Preds/Succs - The SUnits before/after us in the graph. SmallVector Preds; // All sunit predecessors. SmallVector Succs; // All sunit successors. @@ -270,7 +270,7 @@ public: const TargetRegisterClass *CopyDstRC; // Is a special copy node if not null. const TargetRegisterClass *CopySrcRC; - + /// SUnit - Construct an SUnit for pre-regalloc scheduling to represent /// an SDNode and any nodes flagged to it. SUnit(SDNode *node, unsigned nodenum) @@ -353,7 +353,7 @@ /// getDepth - Return the depth of this node, which is the length of the /// maximum path up to any node with has no predecessors. unsigned getDepth() const { - if (!isDepthCurrent) + if (!isDepthCurrent) const_cast(this)->ComputeDepth(); return Depth; } @@ -361,7 +361,7 @@ /// getHeight - Return the height of this node, which is the length of the /// maximum path down to any node with has no successors. unsigned getHeight() const { - if (!isHeightCurrent) + if (!isHeightCurrent) const_cast(this)->ComputeHeight(); return Height; } @@ -393,7 +393,7 @@ return true; return false; } - + /// isSucc - Test if node N is a successor of this node. bool isSucc(SUnit *N) { for (unsigned i = 0, e = (unsigned)Succs.size(); i != e; ++i) @@ -414,17 +414,17 @@ //===--------------------------------------------------------------------===// /// SchedulingPriorityQueue - This interface is used to plug different /// priorities computation algorithms into the list scheduler. It implements - /// the interface of a standard priority queue, where nodes are inserted in + /// the interface of a standard priority queue, where nodes are inserted in /// arbitrary order and returned in priority order. The computation of the /// priority and the representation of the queue are totally up to the /// implementation to decide. - /// + /// class SchedulingPriorityQueue { unsigned CurCycle; public: SchedulingPriorityQueue() : CurCycle(0) {} virtual ~SchedulingPriorityQueue() {} - + virtual void initNodes(std::vector &SUnits) = 0; virtual void addNode(const SUnit *SU) = 0; virtual void updateNode(const SUnit *SU) = 0; @@ -432,7 +432,7 @@ virtual bool empty() const = 0; virtual void push(SUnit *U) = 0; - + void push_all(const std::vector &Nodes) { for (std::vector::const_iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) @@ -457,7 +457,7 @@ unsigned getCurCycle() const { return CurCycle; - } + } }; class ScheduleDAG { @@ -483,7 +483,7 @@ /// using 'dot'. /// void viewGraph(); - + /// EmitSchedule - Insert MachineInstrs into the MachineBasicBlock /// according to the order specified in Sequence. /// @@ -633,7 +633,7 @@ /// Visited - a set of nodes visited during a DFS traversal. BitVector Visited; - /// DFS - make a DFS traversal and mark all nodes affected by the + /// DFS - make a DFS traversal and mark all nodes affected by the /// edge insertion. These nodes will later get new topological indexes /// by means of the Shift method. void DFS(const SUnit *SU, int UpperBound, bool& HasLoop); @@ -648,7 +648,7 @@ public: explicit ScheduleDAGTopologicalSort(std::vector &SUnits); - /// InitDAGTopologicalSorting - create the initial topological + /// InitDAGTopologicalSorting - create the initial topological /// ordering from the DAG to be scheduled. void InitDAGTopologicalSorting(); Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h?rev=122539&r1=122538&r2=122539&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h Thu Dec 23 22:28:06 2010 @@ -35,7 +35,7 @@ class GCFunctionInfo; class ScheduleDAGSDNodes; class LoadInst; - + /// SelectionDAGISel - This is the common base class used for SelectionDAG-based /// pattern-matching instruction selectors. class SelectionDAGISel : public MachineFunctionPass { @@ -55,7 +55,7 @@ explicit SelectionDAGISel(const TargetMachine &tm, CodeGenOpt::Level OL = CodeGenOpt::Default); virtual ~SelectionDAGISel(); - + const TargetLowering &getTargetLowering() { return TLI; } virtual void getAnalysisUsage(AnalysisUsage &AU) const; @@ -63,18 +63,18 @@ virtual bool runOnMachineFunction(MachineFunction &MF); virtual void EmitFunctionEntryCode() {} - + /// PreprocessISelDAG - This hook allows targets to hack on the graph before /// instruction selection starts. virtual void PreprocessISelDAG() {} - + /// PostprocessISelDAG() - This hook allows the target to hack on the graph /// right after selection. virtual void PostprocessISelDAG() {} - + /// Select - Main hook targets implement to select a node. virtual SDNode *Select(SDNode *N) = 0; - + /// SelectInlineAsmMemoryOperand - Select the specified address as a target /// addressing mode, according to the specified constraint code. If this does /// not match or is not implemented, return true. The resultant operands @@ -101,13 +101,13 @@ /// CreateTargetHazardRecognizer - Return a newly allocated hazard recognizer /// to use for this target when scheduling the DAG. virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer(); - - + + // Opcodes used by the DAG state machine: enum BuiltinOpcodes { OPC_Scope, OPC_RecordNode, - OPC_RecordChild0, OPC_RecordChild1, OPC_RecordChild2, OPC_RecordChild3, + OPC_RecordChild0, OPC_RecordChild1, OPC_RecordChild2, OPC_RecordChild3, OPC_RecordChild4, OPC_RecordChild5, OPC_RecordChild6, OPC_RecordChild7, OPC_RecordMemRef, OPC_CaptureGlueInput, @@ -129,7 +129,7 @@ OPC_CheckComplexPat, OPC_CheckAndImm, OPC_CheckOrImm, OPC_CheckFoldableChainNode, - + OPC_EmitInteger, OPC_EmitRegister, OPC_EmitConvertToTarget, @@ -143,7 +143,7 @@ OPC_MarkGlueResults, OPC_CompleteMatch }; - + enum { OPFL_None = 0, // Node has no chain or glue input and isn't variadic. OPFL_Chain = 1, // Node has a chain input. @@ -157,37 +157,37 @@ OPFL_Variadic4 = 5<<4, // Node is variadic, root has 4 fixed inputs. OPFL_Variadic5 = 6<<4, // Node is variadic, root has 5 fixed inputs. OPFL_Variadic6 = 7<<4, // Node is variadic, root has 6 fixed inputs. - + OPFL_VariadicInfo = OPFL_Variadic6 }; - + /// getNumFixedFromVariadicInfo - Transform an EmitNode flags word into the /// number of fixed arity values that should be skipped when copying from the /// root. static inline int getNumFixedFromVariadicInfo(unsigned Flags) { return ((Flags&OPFL_VariadicInfo) >> 4)-1; } - - + + protected: /// DAGSize - Size of DAG being instruction selected. /// unsigned DAGSize; - + /// ISelPosition - Node iterator marking the current position of /// instruction selection as it procedes through the topologically-sorted /// node list. SelectionDAG::allnodes_iterator ISelPosition; - - /// ISelUpdater - helper class to handle updates of the + + /// ISelUpdater - helper class to handle updates of the /// instruction selection graph. class ISelUpdater : public SelectionDAG::DAGUpdateListener { SelectionDAG::allnodes_iterator &ISelPosition; public: explicit ISelUpdater(SelectionDAG::allnodes_iterator &isp) : ISelPosition(isp) {} - + /// NodeDeleted - Handle nodes deleted from the graph. If the /// node being deleted is the current ISelPosition node, update /// ISelPosition. @@ -196,46 +196,46 @@ if (ISelPosition == SelectionDAG::allnodes_iterator(N)) ++ISelPosition; } - + /// NodeUpdated - Ignore updates for now. virtual void NodeUpdated(SDNode *N) {} }; - + /// ReplaceUses - replace all uses of the old node F with the use /// of the new node T. void ReplaceUses(SDValue F, SDValue T) { ISelUpdater ISU(ISelPosition); CurDAG->ReplaceAllUsesOfValueWith(F, T, &ISU); } - + /// ReplaceUses - replace all uses of the old nodes F with the use /// of the new nodes T. void ReplaceUses(const SDValue *F, const SDValue *T, unsigned Num) { ISelUpdater ISU(ISelPosition); CurDAG->ReplaceAllUsesOfValuesWith(F, T, Num, &ISU); } - + /// ReplaceUses - replace all uses of the old node F with the use /// of the new node T. void ReplaceUses(SDNode *F, SDNode *T) { ISelUpdater ISU(ISelPosition); CurDAG->ReplaceAllUsesWith(F, T, &ISU); } - + /// SelectInlineAsmMemoryOperands - Calls to this are automatically generated /// by tblgen. Others should not call it. void SelectInlineAsmMemoryOperands(std::vector &Ops); - + public: // Calls to these predicates are generated by tblgen. bool CheckAndMask(SDValue LHS, ConstantSDNode *RHS, int64_t DesiredMaskS) const; bool CheckOrMask(SDValue LHS, ConstantSDNode *RHS, int64_t DesiredMaskS) const; - - + + /// CheckPatternPredicate - This function is generated by tblgen in the /// target. It runs the specified pattern predicate and returns true if it /// succeeds or false if it fails. The number is a private implementation @@ -253,14 +253,14 @@ assert(0 && "Tblgen should generate the implementation of this!"); return 0; } - + virtual bool CheckComplexPattern(SDNode *Root, SDNode *Parent, SDValue N, unsigned PatternNo, SmallVectorImpl > &Result) { assert(0 && "Tblgen should generate the implementation of this!"); return false; } - + virtual SDValue RunSDNodeXForm(SDValue V, unsigned XFormNo) { assert(0 && "Tblgen shoudl generate this!"); return SDValue(); @@ -269,9 +269,9 @@ SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable, unsigned TableSize); - + private: - + // Calls to these functions are generated by tblgen. SDNode *Select_INLINEASM(SDNode *N); SDNode *Select_UNDEF(SDNode *N); @@ -281,7 +281,7 @@ void DoInstructionSelection(); SDNode *MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTs, const SDValue *Ops, unsigned NumOps, unsigned EmitNodeInfo); - + void PrepareEHLandingPad(); void SelectAllBasicBlocks(const Function &Fn); bool TryToFoldFastISelLoad(const LoadInst *LI, FastISel *FastIS); @@ -292,7 +292,7 @@ bool &HadTailCall); void CodeGenAndEmitDAG(); void LowerArguments(const BasicBlock *BB); - + void ComputeLiveOutVRegInfo(); /// Create the scheduler. If a specific scheduler was specified @@ -300,16 +300,16 @@ /// one preferred by the target. /// ScheduleDAGSDNodes *CreateScheduler(); - + /// OpcodeOffset - This is a cache used to dispatch efficiently into isel /// state machines that start with a OPC_SwitchOpcode node. std::vector OpcodeOffset; - + void UpdateChainsAndGlue(SDNode *NodeToMatch, SDValue InputChain, const SmallVectorImpl &ChainNodesMatched, SDValue InputGlue, const SmallVectorImpl &F, bool isMorphNodeTo); - + }; } Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrInfo.h?rev=122539&r1=122538&r2=122539&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetInstrInfo.h Thu Dec 23 22:28:06 2010 @@ -134,7 +134,7 @@ int &FrameIndex) const { return 0; } - + /// isStoreToStackSlot - If the specified machine instruction is a direct /// store to a stack slot, return the virtual or physical register number of /// the source reg along with the FrameIndex of the loaded stack slot. If @@ -267,7 +267,7 @@ /// This is only invoked in cases where AnalyzeBranch returns success. It /// returns the number of instructions that were removed. virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const { - assert(0 && "Target didn't implement TargetInstrInfo::RemoveBranch!"); + assert(0 && "Target didn't implement TargetInstrInfo::RemoveBranch!"); return 0; } @@ -285,7 +285,7 @@ MachineBasicBlock *FBB, const SmallVectorImpl &Cond, DebugLoc DL) const { - assert(0 && "Target didn't implement TargetInstrInfo::InsertBranch!"); + assert(0 && "Target didn't implement TargetInstrInfo::InsertBranch!"); return 0; } @@ -314,7 +314,7 @@ float Probability, float Confidence) const { return false; } - + /// isProfitableToIfCvt - Second variant of isProfitableToIfCvt, this one /// checks for the case where two basic blocks from true and false path /// of a if-then-else (diamond) are predicated on mutally exclusive @@ -341,7 +341,7 @@ float Probability, float Confidence) const { return false; } - + /// copyPhysReg - Emit instructions to copy a pair of physical registers. virtual void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, DebugLoc DL, @@ -485,7 +485,7 @@ unsigned NumLoads) const { return false; } - + /// ReverseBranchCondition - Reverses the branch condition of the specified /// condition list, returning false on success and true if it cannot be /// reversed. @@ -493,19 +493,19 @@ bool ReverseBranchCondition(SmallVectorImpl &Cond) const { return true; } - + /// insertNoop - Insert a noop into the instruction stream at the specified /// point. - virtual void insertNoop(MachineBasicBlock &MBB, + virtual void insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const; - - + + /// getNoopForMachoTarget - Return the noop instruction to use for a noop. virtual void getNoopForMachoTarget(MCInst &NopInst) const { // Default to just using 'nop' string. } - - + + /// isPredicated - Returns true if the instruction is already predicated. /// virtual bool isPredicated(const MachineInstr *MI) const { @@ -585,7 +585,7 @@ const MachineRegisterInfo *MRI) const { return false; } - + /// FoldImmediate - 'Reg' is known to be defined by a move immediate /// instruction, try to fold the immediate into the use instruction. virtual bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI, Modified: llvm/trunk/include/llvm/Target/TargetInstrItineraries.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrItineraries.h?rev=122539&r1=122538&r2=122539&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrItineraries.h (original) +++ llvm/trunk/include/llvm/Target/TargetInstrItineraries.h Thu Dec 23 22:28:06 2010 @@ -121,7 +121,7 @@ InstrItineraryData(const InstrStage *S, const unsigned *OS, const unsigned *F, const InstrItinerary *I) : Stages(S), OperandCycles(OS), Forwardings(F), Itineraries(I) {} - + /// isEmpty - Returns true if there are no itineraries. /// bool isEmpty() const { return Itineraries == 0; } @@ -135,14 +135,14 @@ } /// beginStage - Return the first stage of the itinerary. - /// + /// const InstrStage *beginStage(unsigned ItinClassIndx) const { unsigned StageIdx = Itineraries[ItinClassIndx].FirstStage; return Stages + StageIdx; } /// endStage - Return the last+1 stage of the itinerary. - /// + /// const InstrStage *endStage(unsigned ItinClassIndx) const { unsigned StageIdx = Itineraries[ItinClassIndx].LastStage; return Stages + StageIdx; Modified: llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp?rev=122539&r1=122538&r2=122539&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp (original) +++ llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp Thu Dec 23 22:28:06 2010 @@ -35,14 +35,14 @@ unsigned RHSLatency = PQ->getLatency(RHSNum); if (LHSLatency < RHSLatency) return true; if (LHSLatency > RHSLatency) return false; - + // After that, if two nodes have identical latencies, look to see if one will // unblock more other nodes than the other. unsigned LHSBlocked = PQ->getNumSolelyBlockNodes(LHSNum); unsigned RHSBlocked = PQ->getNumSolelyBlockNodes(RHSNum); if (LHSBlocked < RHSBlocked) return true; if (LHSBlocked > RHSBlocked) return false; - + // Finally, just to provide a stable ordering, use the node number as a // deciding factor. return LHSNum < RHSNum; @@ -64,7 +64,7 @@ OnlyAvailablePred = &Pred; } } - + return OnlyAvailablePred; } @@ -78,7 +78,7 @@ ++NumNodesBlocking; } NumNodesSolelyBlocking[SU->NodeNum] = NumNodesBlocking; - + Queue.push_back(SU); } @@ -102,10 +102,10 @@ /// node of the same priority that will not make a node available. void LatencyPriorityQueue::AdjustPriorityOfUnscheduledPreds(SUnit *SU) { if (SU->isAvailable) return; // All preds scheduled. - + SUnit *OnlyAvailablePred = getSingleUnscheduledPred(SU); if (OnlyAvailablePred == 0 || !OnlyAvailablePred->isAvailable) return; - + // Okay, we found a single predecessor that is available, but not scheduled. // Since it is available, it must be in the priority queue. First remove it. remove(OnlyAvailablePred); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp?rev=122539&r1=122538&r2=122539&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Thu Dec 23 22:28:06 2010 @@ -40,7 +40,7 @@ static RegisterScheduler tdListDAGScheduler("list-td", "Top-down list scheduler", createTDListDAGScheduler); - + namespace { //===----------------------------------------------------------------------===// /// ScheduleDAGList - The actual list scheduler implementation. This supports @@ -51,7 +51,7 @@ /// AvailableQueue - The priority queue to use for the available SUnits. /// SchedulingPriorityQueue *AvailableQueue; - + /// PendingQueue - This contains all of the instructions whose operands have /// been issued, but their results are not ready yet (due to the latency of /// the operation). Once the operands become available, the instruction is @@ -87,14 +87,14 @@ /// Schedule - Schedule the DAG using list scheduling. void ScheduleDAGList::Schedule() { DEBUG(dbgs() << "********** List Scheduling **********\n"); - + // Build the scheduling graph. BuildSchedGraph(NULL); AvailableQueue->initNodes(SUnits); - + ListScheduleTopDown(); - + AvailableQueue->releaseState(); } @@ -118,7 +118,7 @@ --SuccSU->NumPredsLeft; SuccSU->setDepthToAtLeast(SU->getDepth() + D.getLatency()); - + // If all the node's predecessors are scheduled, this node is ready // to be scheduled. Ignore the special ExitSU node. if (SuccSU->NumPredsLeft == 0 && SuccSU != &ExitSU) @@ -142,7 +142,7 @@ void ScheduleDAGList::ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle) { DEBUG(dbgs() << "*** Scheduling [" << CurCycle << "]: "); DEBUG(SU->dump(this)); - + Sequence.push_back(SU); assert(CurCycle >= SU->getDepth() && "Node scheduled above its depth!"); SU->setDepthToAtLeast(CurCycle); @@ -168,7 +168,7 @@ 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. std::vector NotReady; @@ -187,7 +187,7 @@ assert(PendingQueue[i]->getDepth() > CurCycle && "Negative latency?"); } } - + // If there are no instructions available, don't try to issue anything, and // don't advance the hazard recognizer. if (AvailableQueue->empty()) { @@ -196,24 +196,24 @@ } SUnit *FoundSUnit = 0; - + bool HasNoopHazards = false; while (!AvailableQueue->empty()) { SUnit *CurSUnit = AvailableQueue->pop(); - + ScheduleHazardRecognizer::HazardType HT = HazardRec->getHazardType(CurSUnit); if (HT == ScheduleHazardRecognizer::NoHazard) { FoundSUnit = CurSUnit; break; } - + // Remember if this is a noop hazard. HasNoopHazards |= HT == ScheduleHazardRecognizer::NoopHazard; - + NotReady.push_back(CurSUnit); } - + // Add the nodes that aren't ready back onto the available list. if (!NotReady.empty()) { AvailableQueue->push_all(NotReady); @@ -228,7 +228,7 @@ // If this is a pseudo-op node, we don't want to increment the current // cycle. if (FoundSUnit->Latency) // Don't increment CurCycle for pseudo-ops! - ++CurCycle; + ++CurCycle; } else if (!HasNoopHazards) { // Otherwise, we have a pipeline stall, but no other problem, just advance // the current cycle and try again. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=122539&r1=122538&r2=122539&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Dec 23 22:28:06 2010 @@ -59,9 +59,9 @@ STATISTIC(NumDAGIselRetries,"Number of times dag isel has to try another path"); #ifndef NDEBUG -STATISTIC(NumBBWithOutOfOrderLineInfo, +STATISTIC(NumBBWithOutOfOrderLineInfo, "Number of blocks with out of order line number info"); -STATISTIC(NumMBBWithOutOfOrderLineInfo, +STATISTIC(NumMBBWithOutOfOrderLineInfo, "Number of machine blocks with out of order line number info"); #endif @@ -252,7 +252,7 @@ for (Function::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) { PHINode *PN = dyn_cast(BB->begin()); if (PN == 0) continue; - + ReprocessBlock: // For each block with a PHI node, check to see if any of the input values // are potentially trapping constant expressions. Constant expressions are @@ -262,14 +262,14 @@ for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { ConstantExpr *CE = dyn_cast(PN->getIncomingValue(i)); if (CE == 0 || !CE->canTrap()) continue; - + // The only case we have to worry about is when the edge is critical. // Since this block has a PHI Node, we assume it has multiple input // edges: check to see if the pred has multiple successors. BasicBlock *Pred = PN->getIncomingBlock(i); if (Pred->getTerminator()->getNumSuccessors() == 1) continue; - + // Okay, we have to split this edge. SplitCriticalEdge(Pred->getTerminator(), GetSuccessorNumber(Pred, BB), SDISel, true); @@ -297,7 +297,7 @@ DEBUG(dbgs() << "\n\n\n=== " << Fn.getName() << "\n"); SplitCriticalSideEffectEdges(const_cast(Fn), this); - + CurDAG->init(*MF); FuncInfo->set(Fn, *MF); SDB->init(GFI, *AA); @@ -314,7 +314,7 @@ if (!FuncInfo->ArgDbgValues.empty()) for (MachineRegisterInfo::livein_iterator LI = RegInfo->livein_begin(), E = RegInfo->livein_end(); LI != E; ++LI) - if (LI->second) + if (LI->second) LiveInMap.insert(std::make_pair(LI->first, LI->second)); // Insert DBG_VALUE instructions for function arguments to the entry block. @@ -335,11 +335,11 @@ if (LDI != LiveInMap.end()) { MachineInstr *Def = RegInfo->getVRegDef(LDI->second); MachineBasicBlock::iterator InsertPos = Def; - const MDNode *Variable = + const MDNode *Variable = MI->getOperand(MI->getNumOperands()-1).getMetadata(); unsigned Offset = MI->getOperand(1).getImm(); // Def is never a terminator here, so it is ok to increment InsertPos. - BuildMI(*EntryMBB, ++InsertPos, MI->getDebugLoc(), + BuildMI(*EntryMBB, ++InsertPos, MI->getDebugLoc(), TII.get(TargetOpcode::DBG_VALUE)) .addReg(LDI->second, RegState::Debug) .addImm(Offset).addMetadata(Variable); @@ -348,8 +348,8 @@ // that COPY instructions also need DBG_VALUE, if it is the only // user of LDI->second. MachineInstr *CopyUseMI = NULL; - for (MachineRegisterInfo::use_iterator - UI = RegInfo->use_begin(LDI->second); + for (MachineRegisterInfo::use_iterator + UI = RegInfo->use_begin(LDI->second); MachineInstr *UseMI = UI.skipInstruction();) { if (UseMI->isDebugValue()) continue; if (UseMI->isCopy() && !CopyUseMI && UseMI->getParent() == EntryMBB) { @@ -360,7 +360,7 @@ } if (CopyUseMI) { MachineInstr *NewMI = - BuildMI(*MF, CopyUseMI->getDebugLoc(), + BuildMI(*MF, CopyUseMI->getDebugLoc(), TII.get(TargetOpcode::DBG_VALUE)) .addReg(CopyUseMI->getOperand(0).getReg(), RegState::Debug) .addImm(Offset).addMetadata(Variable); @@ -646,19 +646,19 @@ DEBUG(errs() << "===== Instruction selection begins:\n"); PreprocessISelDAG(); - + // Select target instructions for the DAG. { // Number all nodes with a topological order and set DAGSize. DAGSize = CurDAG->AssignTopologicalOrder(); - + // Create a dummy node (which is not added to allnodes), that adds // a reference to the root node, preventing it from being deleted, // and tracking any changes of the root. HandleSDNode Dummy(CurDAG->getRoot()); ISelPosition = SelectionDAG::allnodes_iterator(CurDAG->getRoot().getNode()); ++ISelPosition; - + // The AllNodes list is now topological-sorted. Visit the // nodes by starting at the end of the list (the root of the // graph) and preceding back toward the beginning (the entry @@ -670,19 +670,19 @@ // makes it theoretically possible to disable the DAGCombiner. if (Node->use_empty()) continue; - + SDNode *ResNode = Select(Node); - + // FIXME: This is pretty gross. 'Select' should be changed to not return // anything at all and this code should be nuked with a tactical strike. - + // If node should not be replaced, continue with the next one. if (ResNode == Node || Node->getOpcode() == ISD::DELETED_NODE) continue; // Replace node. if (ResNode) ReplaceUses(Node, ResNode); - + // If after the replacement this node is not used any more, // remove this dead node. if (Node->use_empty()) { // Don't delete EntryToken, etc. @@ -690,9 +690,9 @@ CurDAG->RemoveDeadNode(Node, &ISU); } } - + CurDAG->setRoot(Dummy.getValue()); - } + } DEBUG(errs() << "===== Instruction selection ends:\n"); @@ -746,13 +746,13 @@ - + bool SelectionDAGISel::TryToFoldFastISelLoad(const LoadInst *LI, FastISel *FastIS) { // Don't try to fold volatile loads. Target has to deal with alignment // constraints. if (LI->isVolatile()) return false; - + // Figure out which vreg this is going into. unsigned LoadReg = FastIS->getRegForValue(LI); assert(LoadReg && "Load isn't already assigned a vreg? "); @@ -762,7 +762,7 @@ MachineRegisterInfo::reg_iterator RI = RegInfo->reg_begin(LoadReg); if (RI == RegInfo->reg_end()) return false; - + // See if there is exactly one use of the vreg. If there are multiple uses, // then the instruction got lowered to multiple machine instructions or the // use of the loaded value ended up being multiple operands of the result, in @@ -770,7 +770,7 @@ MachineRegisterInfo::reg_iterator PostRI = RI; ++PostRI; if (PostRI != RegInfo->reg_end()) return false; - + assert(RI.getOperand().isUse() && "The only use of the vreg must be a use, we haven't emitted the def!"); @@ -797,9 +797,9 @@ Line = L; Col = C; } -} +} -/// CheckLineNumbers - Check if machine basic block instructions follow source +/// CheckLineNumbers - Check if machine basic block instructions follow source /// order or not. static void CheckLineNumbers(const MachineBasicBlock *MBB) { unsigned Line = 0; @@ -817,7 +817,7 @@ Line = L; Col = C; } -} +} #endif void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) { @@ -844,7 +844,7 @@ // Setup an EH landing-pad block. if (FuncInfo->MBB->isLandingPad()) PrepareEHLandingPad(); - + // Lower any arguments needed in this block if this is the entry block. if (LLVMBB == &Fn.getEntryBlock()) LowerArguments(LLVMBB); @@ -897,7 +897,7 @@ TryToFoldFastISelLoad(cast(BeforeInst), FastIS)) { // If we succeeded, don't re-select the load. --BI; - } + } continue; } @@ -1349,7 +1349,7 @@ // uses. if ((Use->getNodeId() < Def->getNodeId() && Use->getNodeId() != -1)) return false; - + // Don't revisit nodes if we already scanned it and didn't fail, we know we // won't fail if we scan it again. if (!Visited.insert(Use)) @@ -1359,7 +1359,7 @@ // Ignore chain uses, they are validated by HandleMergeInputChains. if (Use->getOperand(i).getValueType() == MVT::Other && IgnoreChains) continue; - + SDNode *N = Use->getOperand(i).getNode(); if (N == Def) { if (Use == ImmedUse || Use == Root) @@ -1441,14 +1441,14 @@ break; Root = GU; VT = Root->getValueType(Root->getNumValues()-1); - + // If our query node has a glue result with a use, we've walked up it. If // the user (which has already been selected) has a chain or indirectly uses // the chain, our WalkChainUsers predicate will not consider it. Because of // this, we cannot ignore chains in this predicate. IgnoreChains = false; } - + SmallPtrSet Visited; return !findNonImmUse(Root, N.getNode(), U, Root, Visited, IgnoreChains); @@ -1457,7 +1457,7 @@ SDNode *SelectionDAGISel::Select_INLINEASM(SDNode *N) { std::vector Ops(N->op_begin(), N->op_end()); SelectInlineAsmMemoryOperands(Ops); - + std::vector VTs; VTs.push_back(MVT::Other); VTs.push_back(MVT::Glue); @@ -1476,7 +1476,7 @@ GetVBR(uint64_t Val, const unsigned char *MatcherTable, unsigned &Idx) { assert(Val >= 128 && "Not a VBR"); Val &= 127; // Remove first vbr bit. - + unsigned Shift = 7; uint64_t NextBits; do { @@ -1484,7 +1484,7 @@ Val |= (NextBits&127) << Shift; Shift += 7; } while (NextBits & 128); - + return Val; } @@ -1498,7 +1498,7 @@ const SmallVectorImpl &GlueResultNodesMatched, bool isMorphNodeTo) { SmallVector NowDeadNodes; - + ISelUpdater ISU(ISelPosition); // Now that all the normal results are replaced, we replace the chain and @@ -1510,55 +1510,55 @@ // Replace all the chain results with the final chain we ended up with. for (unsigned i = 0, e = ChainNodesMatched.size(); i != e; ++i) { SDNode *ChainNode = ChainNodesMatched[i]; - + // If this node was already deleted, don't look at it. if (ChainNode->getOpcode() == ISD::DELETED_NODE) continue; - + // Don't replace the results of the root node if we're doing a // MorphNodeTo. if (ChainNode == NodeToMatch && isMorphNodeTo) continue; - + SDValue ChainVal = SDValue(ChainNode, ChainNode->getNumValues()-1); if (ChainVal.getValueType() == MVT::Glue) ChainVal = ChainVal.getValue(ChainVal->getNumValues()-2); assert(ChainVal.getValueType() == MVT::Other && "Not a chain?"); CurDAG->ReplaceAllUsesOfValueWith(ChainVal, InputChain, &ISU); - + // If the node became dead and we haven't already seen it, delete it. if (ChainNode->use_empty() && !std::count(NowDeadNodes.begin(), NowDeadNodes.end(), ChainNode)) NowDeadNodes.push_back(ChainNode); } } - + // If the result produces glue, update any glue results in the matched // pattern with the glue result. if (InputGlue.getNode() != 0) { // Handle any interior nodes explicitly marked. for (unsigned i = 0, e = GlueResultNodesMatched.size(); i != e; ++i) { SDNode *FRN = GlueResultNodesMatched[i]; - + // If this node was already deleted, don't look at it. if (FRN->getOpcode() == ISD::DELETED_NODE) continue; - + assert(FRN->getValueType(FRN->getNumValues()-1) == MVT::Glue && "Doesn't have a glue result"); CurDAG->ReplaceAllUsesOfValueWith(SDValue(FRN, FRN->getNumValues()-1), InputGlue, &ISU); - + // If the node became dead and we haven't already seen it, delete it. if (FRN->use_empty() && !std::count(NowDeadNodes.begin(), NowDeadNodes.end(), FRN)) NowDeadNodes.push_back(FRN); } } - + if (!NowDeadNodes.empty()) CurDAG->RemoveDeadNodes(NowDeadNodes, &ISU); - + DEBUG(errs() << "ISEL: Match complete!\n"); } @@ -1577,17 +1577,17 @@ /// /// The walk we do here is guaranteed to be small because we quickly get down to /// already selected nodes "below" us. -static ChainResult +static ChainResult WalkChainUsers(SDNode *ChainedNode, SmallVectorImpl &ChainedNodesInPattern, SmallVectorImpl &InteriorChainedNodes) { ChainResult Result = CR_Simple; - + for (SDNode::use_iterator UI = ChainedNode->use_begin(), E = ChainedNode->use_end(); UI != E; ++UI) { // Make sure the use is of the chain, not some other value we produce. if (UI.getUse().getValueType() != MVT::Other) continue; - + SDNode *User = *UI; // If we see an already-selected machine node, then we've gone beyond the @@ -1596,7 +1596,7 @@ if (User->isMachineOpcode() || User->getOpcode() == ISD::HANDLENODE) // Root of the graph. continue; - + if (User->getOpcode() == ISD::CopyToReg || User->getOpcode() == ISD::CopyFromReg || User->getOpcode() == ISD::INLINEASM || @@ -1622,7 +1622,7 @@ if (!std::count(ChainedNodesInPattern.begin(), ChainedNodesInPattern.end(), User)) return CR_InducesCycle; - + // Otherwise we found a node that is part of our pattern. For example in: // x = load ptr // y = x+4 @@ -1634,7 +1634,7 @@ InteriorChainedNodes.push_back(User); continue; } - + // If we found a TokenFactor, there are two cases to consider: first if the // TokenFactor is just hanging "below" the pattern we're matching (i.e. no // uses of the TF are in our pattern) we just want to ignore it. Second, @@ -1671,7 +1671,7 @@ case CR_LeadsToInteriorNode: break; // Otherwise, keep processing. } - + // Okay, we know we're in the interesting interior case. The TokenFactor // is now going to be considered part of the pattern so that we rewrite its // uses (it may have uses that are not part of the pattern) with the @@ -1682,7 +1682,7 @@ InteriorChainedNodes.push_back(User); continue; } - + return Result; } @@ -1704,7 +1704,7 @@ InteriorChainedNodes) == CR_InducesCycle) return SDValue(); // Would induce a cycle. } - + // Okay, we have walked all the matched nodes and collected TokenFactor nodes // that we are interested in. Form our input TokenFactor node. SmallVector InputChains; @@ -1715,14 +1715,14 @@ if (N->getOpcode() != ISD::TokenFactor) { if (std::count(InteriorChainedNodes.begin(),InteriorChainedNodes.end(),N)) continue; - + // Otherwise, add the input chain. SDValue InChain = ChainNodesMatched[i]->getOperand(0); assert(InChain.getValueType() == MVT::Other && "Not a chain"); InputChains.push_back(InChain); continue; } - + // If we have a token factor, we want to add all inputs of the token factor // that are not part of the pattern we're matching. for (unsigned op = 0, e = N->getNumOperands(); op != e; ++op) { @@ -1731,13 +1731,13 @@ InputChains.push_back(N->getOperand(op)); } } - + SDValue Res; if (InputChains.size() == 1) return InputChains[0]; return CurDAG->getNode(ISD::TokenFactor, ChainNodesMatched[0]->getDebugLoc(), MVT::Other, &InputChains[0], InputChains.size()); -} +} /// MorphNode - Handle morphing a node in place for the selector. SDNode *SelectionDAGISel:: @@ -1777,7 +1777,7 @@ // Move the glue if needed. if ((EmitNodeInfo & OPFL_GlueOutput) && OldGlueResultNo != -1 && (unsigned)OldGlueResultNo != ResNumResults-1) - CurDAG->ReplaceAllUsesOfValueWith(SDValue(Node, OldGlueResultNo), + CurDAG->ReplaceAllUsesOfValueWith(SDValue(Node, OldGlueResultNo), SDValue(Res, ResNumResults-1)); if ((EmitNodeInfo & OPFL_GlueOutput) != 0) @@ -1786,14 +1786,14 @@ // Move the chain reference if needed. if ((EmitNodeInfo & OPFL_Chain) && OldChainResultNo != -1 && (unsigned)OldChainResultNo != ResNumResults-1) - CurDAG->ReplaceAllUsesOfValueWith(SDValue(Node, OldChainResultNo), + CurDAG->ReplaceAllUsesOfValueWith(SDValue(Node, OldChainResultNo), SDValue(Res, ResNumResults-1)); // Otherwise, no replacement happened because the node already exists. Replace // Uses of the old node with the new one. if (Res != Node) CurDAG->ReplaceAllUsesWith(Node, Res); - + return Res; } @@ -1807,7 +1807,7 @@ assert(RecNo < RecordedNodes.size() && "Invalid CheckSame"); return N == RecordedNodes[RecNo].first; } - + /// CheckPatternPredicate - Implements OP_CheckPatternPredicate. LLVM_ATTRIBUTE_ALWAYS_INLINE static bool CheckPatternPredicate(const unsigned char *MatcherTable, unsigned &MatcherIndex, @@ -1835,7 +1835,7 @@ SDValue N, const TargetLowering &TLI) { MVT::SimpleValueType VT = (MVT::SimpleValueType)MatcherTable[MatcherIndex++]; if (N.getValueType() == VT) return true; - + // Handle the case when VT is iPTR. return VT == MVT::iPTR && N.getValueType() == TLI.getPointerTy(); } @@ -1863,7 +1863,7 @@ MVT::SimpleValueType VT = (MVT::SimpleValueType)MatcherTable[MatcherIndex++]; if (cast(N)->getVT() == VT) return true; - + // Handle the case when VT is iPTR. return VT == MVT::iPTR && cast(N)->getVT() == TLI.getPointerTy(); } @@ -1874,7 +1874,7 @@ int64_t Val = MatcherTable[MatcherIndex++]; if (Val & 128) Val = GetVBR(Val, MatcherTable, MatcherIndex); - + ConstantSDNode *C = dyn_cast(N); return C != 0 && C->getSExtValue() == Val; } @@ -1885,9 +1885,9 @@ int64_t Val = MatcherTable[MatcherIndex++]; if (Val & 128) Val = GetVBR(Val, MatcherTable, MatcherIndex); - + if (N->getOpcode() != ISD::AND) return false; - + ConstantSDNode *C = dyn_cast(N->getOperand(1)); return C != 0 && SDISel.CheckAndMask(N.getOperand(0), C, Val); } @@ -1898,9 +1898,9 @@ int64_t Val = MatcherTable[MatcherIndex++]; if (Val & 128) Val = GetVBR(Val, MatcherTable, MatcherIndex); - + if (N->getOpcode() != ISD::OR) return false; - + ConstantSDNode *C = dyn_cast(N->getOperand(1)); return C != 0 && SDISel.CheckOrMask(N.getOperand(0), C, Val); } @@ -1910,7 +1910,7 @@ /// fail, set Result=true and return anything. If the current predicate is /// known to pass, set Result=false and return the MatcherIndex to continue /// with. If the current predicate is unknown, set Result=false and return the -/// MatcherIndex to continue with. +/// MatcherIndex to continue with. static unsigned IsPredicateKnownToFail(const unsigned char *Table, unsigned Index, SDValue N, bool &Result, SelectionDAGISel &SDISel, @@ -1968,17 +1968,17 @@ struct MatchScope { /// FailIndex - If this match fails, this is the index to continue with. unsigned FailIndex; - + /// NodeStack - The node stack when the scope was formed. SmallVector NodeStack; - + /// NumRecordedNodes - The number of recorded nodes when the scope was formed. unsigned NumRecordedNodes; - + /// NumMatchedMemRefs - The number of matched memref entries. unsigned NumMatchedMemRefs; - - /// InputChain/InputGlue - The current chain/glue + + /// InputChain/InputGlue - The current chain/glue SDValue InputChain, InputGlue; /// HasChainNodesMatched - True if the ChainNodesMatched list is non-empty. @@ -2024,7 +2024,7 @@ case ISD::INLINEASM: return Select_INLINEASM(NodeToMatch); case ISD::UNDEF: return Select_UNDEF(NodeToMatch); } - + assert(!NodeToMatch->isMachineOpcode() && "Node already selected!"); // Set up the node stack with NodeToMatch as the only node on the stack. @@ -2035,38 +2035,38 @@ // MatchScopes - Scopes used when matching, if a match failure happens, this // indicates where to continue checking. SmallVector MatchScopes; - + // RecordedNodes - This is the set of nodes that have been recorded by the // state machine. The second value is the parent of the node, or null if the // root is recorded. SmallVector, 8> RecordedNodes; - + // MatchedMemRefs - This is the set of MemRef's we've seen in the input // pattern. SmallVector MatchedMemRefs; - + // These are the current input chain and glue for use when generating nodes. // Various Emit operations change these. For example, emitting a copytoreg // uses and updates these. SDValue InputChain, InputGlue; - + // ChainNodesMatched - If a pattern matches nodes that have input/output // chains, the OPC_EmitMergeInputChains operation is emitted which indicates // which ones they are. The result is captured into this list so that we can // update the chain results when the pattern is complete. SmallVector ChainNodesMatched; SmallVector GlueResultNodesMatched; - + DEBUG(errs() << "ISEL: Starting pattern match on root node: "; NodeToMatch->dump(CurDAG); errs() << '\n'); - + // Determine where to start the interpreter. Normally we start at opcode #0, // but if the state machine starts with an OPC_SwitchOpcode, then we // accelerate the first lookup (which is guaranteed to be hot) with the // OpcodeOffset table. unsigned MatcherIndex = 0; - + if (!OpcodeOffset.empty()) { // Already computed the OpcodeOffset table, just index into it. if (N.getOpcode() < OpcodeOffset.size()) @@ -2098,7 +2098,7 @@ if (N.getOpcode() < OpcodeOffset.size()) MatcherIndex = OpcodeOffset[N.getOpcode()]; } - + while (1) { assert(MatcherIndex < TableSize && "Invalid index"); #ifndef NDEBUG @@ -2113,7 +2113,7 @@ // determine immediately that the first check (or first several) will // immediately fail, don't even bother pushing a scope for them. unsigned FailIndex; - + while (1) { unsigned NumToSkip = MatcherTable[MatcherIndex++]; if (NumToSkip & 128) @@ -2123,12 +2123,12 @@ FailIndex = 0; break; } - + FailIndex = MatcherIndex+NumToSkip; - + unsigned MatcherIndexOfPredicate = MatcherIndex; (void)MatcherIndexOfPredicate; // silence warning. - + // If we can't evaluate this predicate without pushing a scope (e.g. if // it is a 'MoveParent') or if the predicate succeeds on this node, we // push the scope and evaluate the full predicate chain. @@ -2137,20 +2137,20 @@ Result, *this, RecordedNodes); if (!Result) break; - + DEBUG(errs() << " Skipped scope entry (due to false predicate) at " << "index " << MatcherIndexOfPredicate << ", continuing at " << FailIndex << "\n"); ++NumDAGIselRetries; - + // Otherwise, we know that this case of the Scope is guaranteed to fail, // move to the next case. MatcherIndex = FailIndex; } - + // If the whole scope failed to match, bail. if (FailIndex == 0) break; - + // Push a MatchScope which indicates where to go if the first child fails // to match. MatchScope NewEntry; @@ -2173,7 +2173,7 @@ RecordedNodes.push_back(std::make_pair(N, Parent)); continue; } - + case OPC_RecordChild0: case OPC_RecordChild1: case OPC_RecordChild2: case OPC_RecordChild3: case OPC_RecordChild4: case OPC_RecordChild5: @@ -2189,14 +2189,14 @@ case OPC_RecordMemRef: MatchedMemRefs.push_back(cast(N)->getMemOperand()); continue; - + case OPC_CaptureGlueInput: // If the current node has an input glue, capture it in InputGlue. if (N->getNumOperands() != 0 && N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Glue) InputGlue = N->getOperand(N->getNumOperands()-1); continue; - + case OPC_MoveChild: { unsigned ChildNo = MatcherTable[MatcherIndex++]; if (ChildNo >= N.getNumOperands()) @@ -2205,14 +2205,14 @@ NodeStack.push_back(N); continue; } - + case OPC_MoveParent: // Pop the current node off the NodeStack. NodeStack.pop_back(); assert(!NodeStack.empty() && "Node stack imbalance!"); - N = NodeStack.back(); + N = NodeStack.back(); continue; - + case OPC_CheckSame: if (!::CheckSame(MatcherTable, MatcherIndex, N, RecordedNodes)) break; continue; @@ -2237,11 +2237,11 @@ case OPC_CheckOpcode: if (!::CheckOpcode(MatcherTable, MatcherIndex, N.getNode())) break; continue; - + case OPC_CheckType: if (!::CheckType(MatcherTable, MatcherIndex, N, TLI)) break; continue; - + case OPC_SwitchOpcode: { unsigned CurNodeOpcode = N.getOpcode(); unsigned SwitchStart = MatcherIndex-1; (void)SwitchStart; @@ -2259,20 +2259,20 @@ // If the opcode matches, then we will execute this case. if (CurNodeOpcode == Opc) break; - + // Otherwise, skip over this case. MatcherIndex += CaseSize; } - + // If no cases matched, bail out. if (CaseSize == 0) break; - + // Otherwise, execute the case we found. DEBUG(errs() << " OpcodeSwitch from " << SwitchStart << " to " << MatcherIndex << "\n"); continue; } - + case OPC_SwitchType: { MVT CurNodeVT = N.getValueType().getSimpleVT(); unsigned SwitchStart = MatcherIndex-1; (void)SwitchStart; @@ -2283,22 +2283,22 @@ if (CaseSize & 128) CaseSize = GetVBR(CaseSize, MatcherTable, MatcherIndex); if (CaseSize == 0) break; - + MVT CaseVT = (MVT::SimpleValueType)MatcherTable[MatcherIndex++]; if (CaseVT == MVT::iPTR) CaseVT = TLI.getPointerTy(); - + // If the VT matches, then we will execute this case. if (CurNodeVT == CaseVT) break; - + // Otherwise, skip over this case. MatcherIndex += CaseSize; } - + // If no cases matched, bail out. if (CaseSize == 0) break; - + // Otherwise, execute the case we found. DEBUG(errs() << " TypeSwitch[" << EVT(CurNodeVT).getEVTString() << "] from " << SwitchStart << " to " << MatcherIndex<<'\n'); @@ -2327,7 +2327,7 @@ case OPC_CheckOrImm: if (!::CheckOrImm(MatcherTable, MatcherIndex, N, *this)) break; continue; - + case OPC_CheckFoldableChainNode: { assert(NodeStack.size() != 1 && "No parent node"); // Verify that all intermediate nodes between the root and this one have @@ -2348,7 +2348,7 @@ NodeToMatch, OptLevel, true/*We validate our own chains*/)) break; - + continue; } case OPC_EmitInteger: { @@ -2369,7 +2369,7 @@ CurDAG->getRegister(RegNo, VT), (SDNode*)0)); continue; } - + case OPC_EmitConvertToTarget: { // Convert from IMM/FPIMM to target version. unsigned RecNo = MatcherTable[MatcherIndex++]; @@ -2383,11 +2383,11 @@ const ConstantFP *Val=cast(Imm)->getConstantFPValue(); Imm = CurDAG->getTargetConstantFP(*Val, Imm.getValueType()); } - + RecordedNodes.push_back(std::make_pair(Imm, RecordedNodes[RecNo].second)); continue; } - + case OPC_EmitMergeInputChains1_0: // OPC_EmitMergeInputChains, 1, 0 case OPC_EmitMergeInputChains1_1: { // OPC_EmitMergeInputChains, 1, 1 // These are space-optimized forms of OPC_EmitMergeInputChains. @@ -2395,12 +2395,12 @@ "EmitMergeInputChains should be the first chain producing node"); assert(ChainNodesMatched.empty() && "Should only have one EmitMergeInputChains per match"); - + // Read all of the chained nodes. unsigned RecNo = Opcode == OPC_EmitMergeInputChains1_1; assert(RecNo < RecordedNodes.size() && "Invalid CheckSame"); ChainNodesMatched.push_back(RecordedNodes[RecNo].first.getNode()); - + // FIXME: What if other value results of the node have uses not matched // by this pattern? if (ChainNodesMatched.back() != NodeToMatch && @@ -2408,15 +2408,15 @@ ChainNodesMatched.clear(); break; } - + // Merge the input chains if they are not intra-pattern references. InputChain = HandleMergeInputChains(ChainNodesMatched, CurDAG); - + if (InputChain.getNode() == 0) break; // Failed to merge. continue; } - + case OPC_EmitMergeInputChains: { assert(InputChain.getNode() == 0 && "EmitMergeInputChains should be the first chain producing node"); @@ -2437,7 +2437,7 @@ unsigned RecNo = MatcherTable[MatcherIndex++]; assert(RecNo < RecordedNodes.size() && "Invalid CheckSame"); ChainNodesMatched.push_back(RecordedNodes[RecNo].first.getNode()); - + // FIXME: What if other value results of the node have uses not matched // by this pattern? if (ChainNodesMatched.back() != NodeToMatch && @@ -2446,36 +2446,36 @@ break; } } - + // If the inner loop broke out, the match fails. if (ChainNodesMatched.empty()) break; // Merge the input chains if they are not intra-pattern references. InputChain = HandleMergeInputChains(ChainNodesMatched, CurDAG); - + if (InputChain.getNode() == 0) break; // Failed to merge. continue; } - + case OPC_EmitCopyToReg: { unsigned RecNo = MatcherTable[MatcherIndex++]; assert(RecNo < RecordedNodes.size() && "Invalid CheckSame"); unsigned DestPhysReg = MatcherTable[MatcherIndex++]; - + if (InputChain.getNode() == 0) InputChain = CurDAG->getEntryNode(); - + InputChain = CurDAG->getCopyToReg(InputChain, NodeToMatch->getDebugLoc(), DestPhysReg, RecordedNodes[RecNo].first, InputGlue); - + InputGlue = InputChain.getValue(1); continue; } - + case OPC_EmitNodeXForm: { unsigned XFormNo = MatcherTable[MatcherIndex++]; unsigned RecNo = MatcherTable[MatcherIndex++]; @@ -2484,7 +2484,7 @@ RecordedNodes.push_back(std::pair(Res, (SDNode*) 0)); continue; } - + case OPC_EmitNode: case OPC_MorphNodeTo: { uint16_t TargetOpc = MatcherTable[MatcherIndex++]; @@ -2499,12 +2499,12 @@ if (VT == MVT::iPTR) VT = TLI.getPointerTy().SimpleTy; VTs.push_back(VT); } - + if (EmitNodeInfo & OPFL_Chain) VTs.push_back(MVT::Other); if (EmitNodeInfo & OPFL_GlueOutput) VTs.push_back(MVT::Glue); - + // This is hot code, so optimize the two most common cases of 1 and 2 // results. SDVTList VTList; @@ -2522,11 +2522,11 @@ unsigned RecNo = MatcherTable[MatcherIndex++]; if (RecNo & 128) RecNo = GetVBR(RecNo, MatcherTable, MatcherIndex); - + assert(RecNo < RecordedNodes.size() && "Invalid EmitNode"); Ops.push_back(RecordedNodes[RecNo].first); } - + // If there are variadic operands to add, handle them now. if (EmitNodeInfo & OPFL_VariadicInfo) { // Determine the start index to copy from. @@ -2543,13 +2543,13 @@ Ops.push_back(V); } } - + // If this has chain/glue inputs, add them. if (EmitNodeInfo & OPFL_Chain) Ops.push_back(InputChain); if ((EmitNodeInfo & OPFL_GlueInput) && InputGlue.getNode() != 0) Ops.push_back(InputGlue); - + // Create the node. SDNode *Res = 0; if (Opcode != OPC_MorphNodeTo) { @@ -2557,19 +2557,19 @@ // add the results to the RecordedNodes list. Res = CurDAG->getMachineNode(TargetOpc, NodeToMatch->getDebugLoc(), VTList, Ops.data(), Ops.size()); - + // Add all the non-glue/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::Glue) break; RecordedNodes.push_back(std::pair(SDValue(Res, i), (SDNode*) 0)); } - + } else { Res = MorphNode(NodeToMatch, TargetOpc, VTList, Ops.data(), Ops.size(), EmitNodeInfo); } - + // If the node had chain/glue results, update our notion of the current // chain and glue. if (EmitNodeInfo & OPFL_GlueOutput) { @@ -2592,11 +2592,11 @@ cast(Res) ->setMemRefs(MemRefs, MemRefs + MatchedMemRefs.size()); } - + DEBUG(errs() << " " << (Opcode == OPC_MorphNodeTo ? "Morphed" : "Created") << " node: "; Res->dump(CurDAG); errs() << "\n"); - + // If this was a MorphNodeTo then we're completely done! if (Opcode == OPC_MorphNodeTo) { // Update chain and glue uses. @@ -2604,13 +2604,13 @@ InputGlue, GlueResultNodesMatched, true); return Res; } - + continue; } - + case OPC_MarkGlueResults: { unsigned NumNodes = MatcherTable[MatcherIndex++]; - + // Read and remember all the glue-result nodes. for (unsigned i = 0; i != NumNodes; ++i) { unsigned RecNo = MatcherTable[MatcherIndex++]; @@ -2622,7 +2622,7 @@ } continue; } - + case OPC_CompleteMatch: { // The match has been completed, and any new nodes (if any) have been // created. Patch up references to the matched dag to use the newly @@ -2633,10 +2633,10 @@ unsigned ResSlot = MatcherTable[MatcherIndex++]; if (ResSlot & 128) ResSlot = GetVBR(ResSlot, MatcherTable, MatcherIndex); - + assert(ResSlot < RecordedNodes.size() && "Invalid CheckSame"); SDValue Res = RecordedNodes[ResSlot].first; - + assert(i < NodeToMatch->getNumValues() && NodeToMatch->getValueType(i) != MVT::Other && NodeToMatch->getValueType(i) != MVT::Glue && @@ -2653,20 +2653,20 @@ // If the root node defines glue, add it to the glue nodes to update list. if (NodeToMatch->getValueType(NodeToMatch->getNumValues()-1) == MVT::Glue) GlueResultNodesMatched.push_back(NodeToMatch); - + // Update chain and glue uses. UpdateChainsAndGlue(NodeToMatch, InputChain, ChainNodesMatched, InputGlue, GlueResultNodesMatched, false); - + assert(NodeToMatch->use_empty() && "Didn't replace all uses of the node?"); - + // FIXME: We just return here, which interacts correctly with SelectRoot // above. We should fix this to not return an SDNode* anymore. return 0; } } - + // If the code reached this point, then the match failed. See if there is // another child to try in the current 'Scope', otherwise pop it until we // find a case to check. @@ -2689,9 +2689,9 @@ if (LastScope.NumMatchedMemRefs != MatchedMemRefs.size()) MatchedMemRefs.resize(LastScope.NumMatchedMemRefs); MatcherIndex = LastScope.FailIndex; - + DEBUG(errs() << " Continuing at " << MatcherIndex << "\n"); - + InputChain = LastScope.InputChain; InputGlue = LastScope.InputGlue; if (!LastScope.HasChainNodesMatched) @@ -2712,21 +2712,21 @@ LastScope.FailIndex = MatcherIndex+NumToSkip; break; } - + // End of this scope, pop it and try the next child in the containing // scope. MatchScopes.pop_back(); } } } - + void SelectionDAGISel::CannotYetSelect(SDNode *N) { std::string msg; raw_string_ostream Msg(msg); Msg << "Cannot select: "; - + if (N->getOpcode() != ISD::INTRINSIC_W_CHAIN && N->getOpcode() != ISD::INTRINSIC_WO_CHAIN && N->getOpcode() != ISD::INTRINSIC_VOID) { Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp?rev=122539&r1=122538&r2=122539&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Thu Dec 23 22:28:06 2010 @@ -1687,7 +1687,7 @@ // The number of uOps for load / store multiple are determined by the number // registers. - // + // // On Cortex-A8, each pair of register loads / stores can be scheduled on the // same cycle. The scheduling for the first load / store must be done // separately by assuming the the address is not 64-bit aligned. Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=122539&r1=122538&r2=122539&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Thu Dec 23 22:28:06 2010 @@ -2039,7 +2039,7 @@ SDValue Ops[] = { FalseVal, True, CC, CCR, InFlag }; return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 5); } - + return 0; } Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp?rev=122539&r1=122538&r2=122539&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp Thu Dec 23 22:28:06 2010 @@ -201,7 +201,7 @@ // through a stub. if (!isDecl && !GV->isWeakForLinker()) return false; - + // Unless we have a symbol with hidden visibility, we have to go through a // normal $non_lazy_ptr stub because this symbol might be resolved late. if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference. @@ -219,7 +219,7 @@ return 13; else if (isCortexA9()) return 8; - + // Otherwise, just return a sensible default. return 10; } Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.h?rev=122539&r1=122538&r2=122539&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMSubtarget.h (original) +++ llvm/trunk/lib/Target/ARM/ARMSubtarget.h Thu Dec 23 22:28:06 2010 @@ -205,7 +205,7 @@ const std::string & getCPUString() const { return CPUString; } unsigned getMispredictionPenalty() const; - + /// enablePostRAScheduler - True at 'More' optimization. bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, TargetSubtarget::AntiDepBreakMode& Mode, Modified: llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h?rev=122539&r1=122538&r2=122539&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h (original) +++ llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h Thu Dec 23 22:28:06 2010 @@ -20,7 +20,7 @@ namespace llvm { class TargetInstrInfo; - + /// SPUHazardRecognizer class SPUHazardRecognizer : public ScheduleHazardRecognizer { Modified: llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp?rev=122539&r1=122538&r2=122539&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp Thu Dec 23 22:28:06 2010 @@ -26,7 +26,7 @@ // // This models the dispatch group formation of the PPC970 processor. Dispatch // groups are bundles of up to five instructions that can contain various mixes -// of instructions. The PPC970 can dispatch a peak of 4 non-branch and one +// of instructions. The PPC970 can dispatch a peak of 4 non-branch and one // branch instruction per-cycle. // // There are a number of restrictions to dispatch group formation: some @@ -55,14 +55,14 @@ void PPCHazardRecognizer970::EndDispatchGroup() { DEBUG(errs() << "=== Start of dispatch group\n"); NumIssued = 0; - + // Structural hazard info. HasCTRSet = false; NumStores = 0; } -PPCII::PPC970_Unit +PPCII::PPC970_Unit PPCHazardRecognizer970::GetInstrType(unsigned Opcode, bool &isFirst, bool &isSingle, bool &isCracked, @@ -72,14 +72,14 @@ return PPCII::PPC970_Pseudo; } Opcode = ~Opcode; - + const TargetInstrDesc &TID = TII.get(Opcode); - + isLoad = TID.mayLoad(); isStore = TID.mayStore(); - + uint64_t TSFlags = TID.TSFlags; - + isFirst = TSFlags & PPCII::PPC970_First; isSingle = TSFlags & PPCII::PPC970_Single; isCracked = TSFlags & PPCII::PPC970_Cracked; @@ -96,7 +96,7 @@ return true; if (Ptr2 == StorePtr1[i] && Ptr1 == StorePtr2[i]) return true; - + // Okay, we don't have an exact match, if this is an indexed offset, see if // we have overlap (which happens during fp->int conversion for example). if (StorePtr2[i] == Ptr2) { @@ -125,23 +125,23 @@ getHazardType(SUnit *SU) { const SDNode *Node = SU->getNode()->getGluedMachineNode(); bool isFirst, isSingle, isCracked, isLoad, isStore; - PPCII::PPC970_Unit InstrType = + PPCII::PPC970_Unit InstrType = GetInstrType(Node->getOpcode(), isFirst, isSingle, isCracked, isLoad, isStore); - if (InstrType == PPCII::PPC970_Pseudo) return NoHazard; + if (InstrType == PPCII::PPC970_Pseudo) return NoHazard; unsigned Opcode = Node->getMachineOpcode(); // We can only issue a PPC970_First/PPC970_Single instruction (such as // crand/mtspr/etc) if this is the first cycle of the dispatch group. if (NumIssued != 0 && (isFirst || isSingle)) return Hazard; - + // If this instruction is cracked into two ops by the decoder, we know that // it is not a branch and that it cannot issue if 3 other instructions are // already in the dispatch group. if (isCracked && NumIssued > 2) return Hazard; - + switch (InstrType) { default: llvm_unreachable("Unknown instruction type!"); case PPCII::PPC970_FXU: @@ -159,11 +159,11 @@ case PPCII::PPC970_BRU: break; } - + // Do not allow MTCTR and BCTRL to be in the same dispatch group. if (HasCTRSet && (Opcode == PPC::BCTRL_Darwin || Opcode == PPC::BCTRL_SVR4)) return NoopHazard; - + // If this is a load following a store, make sure it's not to the same or // overlapping address. if (isLoad && NumStores) { @@ -212,27 +212,27 @@ LoadSize = 16; break; } - - if (isLoadOfStoredAddress(LoadSize, + + if (isLoadOfStoredAddress(LoadSize, Node->getOperand(0), Node->getOperand(1))) return NoopHazard; } - + return NoHazard; } void PPCHazardRecognizer970::EmitInstruction(SUnit *SU) { const SDNode *Node = SU->getNode()->getGluedMachineNode(); bool isFirst, isSingle, isCracked, isLoad, isStore; - PPCII::PPC970_Unit InstrType = + PPCII::PPC970_Unit InstrType = GetInstrType(Node->getOpcode(), isFirst, isSingle, isCracked, isLoad, isStore); - if (InstrType == PPCII::PPC970_Pseudo) return; + if (InstrType == PPCII::PPC970_Pseudo) return; unsigned Opcode = Node->getMachineOpcode(); // Update structural hazard information. if (Opcode == PPC::MTCTR) HasCTRSet = true; - + // Track the address stored to. if (isStore) { unsigned ThisStoreSize; @@ -278,22 +278,22 @@ ThisStoreSize = 16; break; } - + StoreSize[NumStores] = ThisStoreSize; StorePtr1[NumStores] = Node->getOperand(1); StorePtr2[NumStores] = Node->getOperand(2); ++NumStores; } - + if (InstrType == PPCII::PPC970_BRU || isSingle) NumIssued = 4; // Terminate a d-group. ++NumIssued; - + // If this instruction is cracked into two ops by the decoder, remember that // we issued two pieces. if (isCracked) ++NumIssued; - + if (NumIssued == 5) EndDispatchGroup(); } Modified: llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.h?rev=122539&r1=122538&r2=122539&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.h (original) +++ llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.h Thu Dec 23 22:28:06 2010 @@ -19,7 +19,7 @@ #include "PPCInstrInfo.h" namespace llvm { - + /// PPCHazardRecognizer970 - This class defines a finite state automata that /// models the dispatch logic on the PowerPC 970 (aka G5) processor. This /// promotes good dispatch group formation and implements noop insertion to @@ -28,14 +28,14 @@ /// or storing then loading from the same address within a dispatch group. class PPCHazardRecognizer970 : public ScheduleHazardRecognizer { const TargetInstrInfo &TII; - + unsigned NumIssued; // Number of insts issued, including advanced cycles. - + // Various things that can cause a structural hazard. - + // HasCTRSet - If the CTR register is set in this group, disallow BCTRL. bool HasCTRSet; - + // StoredPtr - Keep track of the address of any store. If we see a load from // the same address (or one that aliases it), disallow the store. We can have // up to four stores in one dispatch group, hence we track up to 4. @@ -45,24 +45,24 @@ SDValue StorePtr1[4], StorePtr2[4]; unsigned StoreSize[4]; unsigned NumStores; - + public: PPCHazardRecognizer970(const TargetInstrInfo &TII); virtual HazardType getHazardType(SUnit *SU); virtual void EmitInstruction(SUnit *SU); virtual void AdvanceCycle(); - + private: /// EndDispatchGroup - Called when we are finishing a new dispatch group. /// void EndDispatchGroup(); - + /// GetInstrType - Classify the specified powerpc opcode according to its /// pipeline. PPCII::PPC970_Unit GetInstrType(unsigned Opcode, bool &isFirst, bool &isSingle,bool &isCracked, bool &isLoad, bool &isStore); - + bool isLoadOfStoredAddress(unsigned LoadSize, SDValue Ptr1, SDValue Ptr2) const; }; Modified: llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp?rev=122539&r1=122538&r2=122539&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Thu Dec 23 22:28:06 2010 @@ -49,16 +49,16 @@ : SelectionDAGISel(tm), TM(tm), PPCLowering(*TM.getTargetLowering()), PPCSubTarget(*TM.getSubtargetImpl()) {} - + virtual bool runOnMachineFunction(MachineFunction &MF) { // Make sure we re-emit a set of the global base reg if necessary GlobalBaseReg = 0; SelectionDAGISel::runOnMachineFunction(MF); - + InsertVRSaveCode(MF); return true; } - + /// getI32Imm - Return a target constant with the specified value, of type /// i32. inline SDValue getI32Imm(unsigned Imm) { @@ -70,13 +70,13 @@ inline SDValue getI64Imm(uint64_t Imm) { return CurDAG->getTargetConstant(Imm, MVT::i64); } - + /// getSmallIPtrImm - Return a target constant of pointer type. inline SDValue getSmallIPtrImm(unsigned Imm) { return CurDAG->getTargetConstant(Imm, PPCLowering.getPointerTy()); } - - /// isRunOfOnes - Returns true iff Val consists of one contiguous run of 1s + + /// isRunOfOnes - Returns true iff Val consists of one contiguous run of 1s /// with any number of 0s on either side. The 1s are allowed to wrap from /// LSB to MSB, so 0x000FFF0, 0x0000FFFF, and 0xFF0000FF are all runs. /// 0x0F0F0000 is not, since all 1s are not contiguous. @@ -87,15 +87,15 @@ /// rotate and mask opcode and mask operation. static bool isRotateAndMask(SDNode *N, unsigned Mask, bool isShiftMask, unsigned &SH, unsigned &MB, unsigned &ME); - + /// getGlobalBaseReg - insert code into the entry mbb to materialize the PIC /// base register. Return the virtual register that holds this value. SDNode *getGlobalBaseReg(); - + // Select - Convert the specified operand from a target-independent to a // target-specific node if it hasn't already been changed. SDNode *Select(SDNode *N); - + SDNode *SelectBitfieldInsert(SDNode *N); /// SelectCC - Select a comparison of the specified values with the @@ -108,7 +108,7 @@ SDValue &Base) { return PPCLowering.SelectAddressRegImm(N, Disp, Base, *CurDAG); } - + /// SelectAddrImmOffs - Return true if the operand is valid for a preinc /// immediate field. Because preinc imms have already been validated, just /// accept it. @@ -116,14 +116,14 @@ Out = N; return true; } - + /// SelectAddrIdx - Given the specified addressed, check to see if it can be /// represented as an indexed [r+r] operation. Returns false if it can /// be represented by [r+imm], which are preferred. bool SelectAddrIdx(SDValue N, SDValue &Base, SDValue &Index) { return PPCLowering.SelectAddressRegReg(N, Base, Index, *CurDAG); } - + /// SelectAddrIdxOnly - Given the specified addressed, force it to be /// represented as an indexed [r+r] operation. bool SelectAddrIdxOnly(SDValue N, SDValue &Base, SDValue &Index) { @@ -136,7 +136,7 @@ bool SelectAddrImmShift(SDValue N, SDValue &Disp, SDValue &Base) { return PPCLowering.SelectAddressRegImmShift(N, Disp, Base, *CurDAG); } - + /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for /// inline asm expressions. It is always correct to compute the value into /// a register. The case of adding a (possibly relocatable) constant to a @@ -148,13 +148,13 @@ OutOps.push_back(Op); return false; } - + void InsertVRSaveCode(MachineFunction &MF); virtual const char *getPassName() const { return "PowerPC DAG->DAG Pattern Instruction Selection"; - } - + } + /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for /// this target when scheduling the DAG. virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer() { @@ -162,12 +162,12 @@ // now, always return a PPC970 recognizer. const TargetInstrInfo *II = TM.getInstrInfo(); assert(II && "No InstrInfo?"); - return new PPCHazardRecognizer970(*II); + return new PPCHazardRecognizer970(*II); } // Include the pieces autogenerated from the target description. #include "PPCGenDAGISel.inc" - + private: SDNode *SelectSETCC(SDNode *N); }; @@ -178,19 +178,19 @@ /// check to see if we need to save/restore VRSAVE. If so, do it. void PPCDAGToDAGISel::InsertVRSaveCode(MachineFunction &Fn) { // Check to see if this function uses vector registers, which means we have to - // save and restore the VRSAVE register and update it with the regs we use. + // save and restore the VRSAVE register and update it with the regs we use. // // In this case, there will be virtual registers of vector type created // by the scheduler. Detect them now. bool HasVectorVReg = false; - for (unsigned i = TargetRegisterInfo::FirstVirtualRegister, + for (unsigned i = TargetRegisterInfo::FirstVirtualRegister, e = RegInfo->getLastVirtReg()+1; i != e; ++i) if (RegInfo->getRegClass(i) == &PPC::VRRCRegClass) { HasVectorVReg = true; break; } if (!HasVectorVReg) return; // nothing to do. - + // If we have a vector register, we want to emit code into the entry and exit // blocks to save and restore the VRSAVE register. We do this here (instead // of marking all vector instructions as clobbering VRSAVE) for two reasons: @@ -205,7 +205,7 @@ // function and one for the value after having bits or'd into it. unsigned InVRSAVE = RegInfo->createVirtualRegister(&PPC::GPRCRegClass); unsigned UpdatedVRSAVE = RegInfo->createVirtualRegister(&PPC::GPRCRegClass); - + const TargetInstrInfo &TII = *TM.getInstrInfo(); MachineBasicBlock &EntryBB = *Fn.begin(); DebugLoc dl; @@ -218,21 +218,21 @@ BuildMI(EntryBB, IP, dl, TII.get(PPC::UPDATE_VRSAVE), UpdatedVRSAVE).addReg(InVRSAVE); BuildMI(EntryBB, IP, dl, TII.get(PPC::MTVRSAVE)).addReg(UpdatedVRSAVE); - + // Find all return blocks, outputting a restore in each epilog. for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) { if (!BB->empty() && BB->back().getDesc().isReturn()) { IP = BB->end(); --IP; - + // Skip over all terminator instructions, which are part of the return // sequence. MachineBasicBlock::iterator I2 = IP; while (I2 != BB->begin() && (--I2)->getDesc().isTerminator()) IP = I2; - + // Emit: MTVRSAVE InVRSave BuildMI(*BB, IP, dl, TII.get(PPC::MTVRSAVE)).addReg(InVRSAVE); - } + } } } @@ -338,8 +338,8 @@ return false; } -bool PPCDAGToDAGISel::isRotateAndMask(SDNode *N, unsigned Mask, - bool isShiftMask, unsigned &SH, +bool PPCDAGToDAGISel::isRotateAndMask(SDNode *N, unsigned Mask, + bool isShiftMask, unsigned &SH, unsigned &MB, unsigned &ME) { // Don't even go down this path for i64, since different logic will be // necessary for rldicl/rldicr/rldimi. @@ -352,13 +352,13 @@ if (N->getNumOperands() != 2 || !isInt32Immediate(N->getOperand(1).getNode(), Shift) || (Shift > 31)) return false; - + if (Opcode == ISD::SHL) { // apply shift left to mask if it comes first if (isShiftMask) Mask = Mask << Shift; // determine which bits are made indeterminant by shift Indeterminant = ~(0xFFFFFFFFu << Shift); - } else if (Opcode == ISD::SRL) { + } else if (Opcode == ISD::SRL) { // apply shift right to mask if it comes first if (isShiftMask) Mask = Mask >> Shift; // determine which bits are made indeterminant by shift @@ -370,7 +370,7 @@ } else { return false; } - + // if the mask doesn't intersect any Indeterminant bits if (Mask && !(Mask & Indeterminant)) { SH = Shift & 31; @@ -386,14 +386,14 @@ SDValue Op0 = N->getOperand(0); SDValue Op1 = N->getOperand(1); DebugLoc dl = N->getDebugLoc(); - + APInt LKZ, LKO, RKZ, RKO; CurDAG->ComputeMaskedBits(Op0, APInt::getAllOnesValue(32), LKZ, LKO); CurDAG->ComputeMaskedBits(Op1, APInt::getAllOnesValue(32), RKZ, RKO); - + unsigned TargetMask = LKZ.getZExtValue(); unsigned InsertMask = RKZ.getZExtValue(); - + if ((TargetMask | InsertMask) == 0xFFFFFFFF) { unsigned Op0Opc = Op0.getOpcode(); unsigned Op1Opc = Op1.getOpcode(); @@ -421,7 +421,7 @@ std::swap(TargetMask, InsertMask); } } - + unsigned MB, ME; if (InsertMask && isRunOfOnes(InsertMask, MB, ME)) { SDValue Tmp1, Tmp2; @@ -457,7 +457,7 @@ ISD::CondCode CC, DebugLoc dl) { // Always select the LHS. unsigned Opc; - + if (LHS.getValueType() == MVT::i32) { unsigned Imm; if (CC == ISD::SETEQ || CC == ISD::SETNE) { @@ -470,11 +470,11 @@ if (isInt<16>((int)Imm)) return SDValue(CurDAG->getMachineNode(PPC::CMPWI, dl, MVT::i32, LHS, getI32Imm(Imm & 0xFFFF)), 0); - + // For non-equality comparisons, the default code would materialize the // constant, then compare against it, like this: // lis r2, 4660 - // ori r2, r2, 22136 + // ori r2, r2, 22136 // cmpw cr0, r3, r2 // Since we are just comparing for equality, we can emit this instead: // xoris r0,r3,0x1234 @@ -511,11 +511,11 @@ if (isInt<16>(Imm)) return SDValue(CurDAG->getMachineNode(PPC::CMPDI, dl, MVT::i64, LHS, getI32Imm(Imm & 0xFFFF)), 0); - + // For non-equality comparisons, the default code would materialize the // constant, then compare against it, like this: // lis r2, 4660 - // ori r2, r2, 22136 + // ori r2, r2, 22136 // cmpd cr0, r3, r2 // Since we are just comparing for equality, we can emit this instead: // xoris r0,r3,0x1234 @@ -604,9 +604,9 @@ case ISD::SETUNE: case ISD::SETNE: Invert = true; return 2; // !Bit #2 = SETUNE case ISD::SETO: Invert = true; return 3; // !Bit #3 = SETO - case ISD::SETUEQ: - case ISD::SETOGE: - case ISD::SETOLE: + case ISD::SETUEQ: + case ISD::SETOGE: + case ISD::SETOLE: case ISD::SETONE: llvm_unreachable("Invalid branch code: should be expanded by legalize"); // These are invalid for floating point. Assume integer. @@ -637,7 +637,7 @@ SDValue AD = SDValue(CurDAG->getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Glue, Op, getI32Imm(~0U)), 0); - return CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, AD, Op, + return CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, AD, Op, AD.getValue(1)); } case ISD::SETLT: { @@ -659,8 +659,8 @@ case ISD::SETEQ: 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, + return CurDAG->SelectNodeTo(N, PPC::ADDZE, MVT::i32, + SDValue(CurDAG->getMachineNode(PPC::LI, dl, MVT::i32, getI32Imm(0)), 0), Op.getValue(1)); @@ -681,35 +681,35 @@ } case ISD::SETGT: { SDValue Ops[] = { Op, getI32Imm(1), getI32Imm(31), getI32Imm(31) }; - Op = SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32, Ops, 4), + Op = SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32, Ops, 4), 0); - return CurDAG->SelectNodeTo(N, PPC::XORI, MVT::i32, Op, + return CurDAG->SelectNodeTo(N, PPC::XORI, MVT::i32, Op, getI32Imm(1)); } } } } - + bool Inv; int OtherCondIdx; unsigned Idx = getCRIdxForSetCC(CC, Inv, OtherCondIdx); SDValue CCReg = SelectCC(N->getOperand(0), N->getOperand(1), CC, dl); SDValue IntCR; - + // Force the ccreg into CR7. SDValue CR7Reg = CurDAG->getRegister(PPC::CR7, MVT::i32); - + SDValue InFlag(0, 0); // Null incoming flag value. - CCReg = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, CR7Reg, CCReg, + CCReg = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, CR7Reg, CCReg, InFlag).getValue(1); - + if (PPCSubTarget.isGigaProcessor() && OtherCondIdx == -1) IntCR = SDValue(CurDAG->getMachineNode(PPC::MFOCRF, dl, MVT::i32, CR7Reg, CCReg), 0); else IntCR = SDValue(CurDAG->getMachineNode(PPC::MFCRpseud, dl, MVT::i32, CR7Reg, CCReg), 0); - + SDValue Ops[] = { IntCR, getI32Imm((32-(3-Idx)) & 31), getI32Imm(31), getI32Imm(31) }; if (OtherCondIdx == -1 && !Inv) @@ -728,7 +728,7 @@ // Get the other bit of the comparison. Ops[1] = getI32Imm((32-(3-OtherCondIdx)) & 31); - SDValue OtherCond = + SDValue OtherCond = SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32, Ops, 4), 0); return CurDAG->SelectNodeTo(N, PPC::OR, MVT::i32, Tmp, OtherCond); @@ -744,7 +744,7 @@ switch (N->getOpcode()) { default: break; - + case ISD::Constant: { if (N->getValueType(0) == MVT::i64) { // Get 64 bit value. @@ -753,12 +753,12 @@ unsigned Remainder = 0; // Assume no shift required. unsigned Shift = 0; - + // If it can't be represented as a 32 bit value. if (!isInt<32>(Imm)) { Shift = CountTrailingZeros_64(Imm); int64_t ImmSh = static_cast(Imm) >> Shift; - + // If the shifted value fits 32 bits. if (isInt<32>(ImmSh)) { // Go with the shifted value. @@ -770,14 +770,14 @@ Imm >>= 32; } } - + // Intermediate operand. SDNode *Result; // Handle first 32 bits. unsigned Lo = Imm & 0xFFFF; unsigned Hi = (Imm >> 16) & 0xFFFF; - + // Simple value. if (isInt<16>(Imm)) { // Just the Lo bits. @@ -793,7 +793,7 @@ // Just the Hi bits. Result = CurDAG->getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(Hi)); } - + // If no shift, we're done. if (!Shift) return Result; @@ -809,22 +809,22 @@ if ((Hi = (Remainder >> 16) & 0xFFFF)) { Result = CurDAG->getMachineNode(PPC::ORIS8, dl, MVT::i64, SDValue(Result, 0), getI32Imm(Hi)); - } + } if ((Lo = Remainder & 0xFFFF)) { Result = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64, SDValue(Result, 0), getI32Imm(Lo)); } - + return Result; } break; } - + case ISD::SETCC: return SelectSETCC(N); case PPCISD::GlobalBaseReg: return getGlobalBaseReg(); - + case ISD::FrameIndex: { int FI = cast(N)->getIndex(); SDValue TFI = CurDAG->getTargetFrameIndex(FI, N->getValueType(0)); @@ -846,11 +846,11 @@ return CurDAG->getMachineNode(PPC::MFCRpseud, dl, MVT::i32, N->getOperand(0), InFlag); } - + case ISD::SDIV: { // FIXME: since this depends on the setting of the carry flag from the srawi // we should really be making notes about that for the scheduler. - // FIXME: It sure would be nice if we could cheaply recognize the + // FIXME: It sure would be nice if we could cheaply recognize the // srl/add/sra pattern the dag combiner will generate for this as // sra/addze rather than having to handle sdiv ourselves. oh well. unsigned Imm; @@ -860,7 +860,7 @@ SDNode *Op = CurDAG->getMachineNode(PPC::SRAWI, dl, MVT::i32, MVT::Glue, N0, getI32Imm(Log2_32(Imm))); - return CurDAG->SelectNodeTo(N, PPC::ADDZE, MVT::i32, + return CurDAG->SelectNodeTo(N, PPC::ADDZE, MVT::i32, SDValue(Op, 0), SDValue(Op, 1)); } else if ((signed)Imm < 0 && isPowerOf2_32(-Imm)) { SDNode *Op = @@ -873,24 +873,24 @@ return CurDAG->SelectNodeTo(N, PPC::NEG, MVT::i32, PT); } } - + // Other cases are autogenerated. break; } - + case ISD::LOAD: { // Handle preincrement loads. LoadSDNode *LD = cast(N); EVT LoadedVT = LD->getMemoryVT(); - + // Normal loads are handled by code generated from the .td file. if (LD->getAddressingMode() != ISD::PRE_INC) break; - + SDValue Offset = LD->getOffset(); if (isa(Offset) || Offset.getOpcode() == ISD::TargetGlobalAddress) { - + unsigned Opcode; bool isSExt = LD->getExtensionType() == ISD::SEXTLOAD; if (LD->getValueType(0) != MVT::i64) { @@ -917,7 +917,7 @@ case MVT::i8: Opcode = PPC::LBZU8; break; } } - + SDValue Chain = LD->getChain(); SDValue Base = LD->getBasePtr(); SDValue Ops[] = { Offset, Base, Chain }; @@ -929,7 +929,7 @@ llvm_unreachable("R+R preindex loads not supported yet!"); } } - + case ISD::AND: { unsigned Imm, Imm2, SH, MB, ME; @@ -944,7 +944,7 @@ // If this is just a masked value where the input is not handled above, and // is not a rotate-left (handled by a pattern in the .td file), emit rlwinm if (isInt32Immediate(N->getOperand(1), Imm) && - isRunOfOnes(Imm, MB, ME) && + isRunOfOnes(Imm, MB, ME) && N->getOperand(0).getOpcode() != ISD::ROTL) { SDValue Val = N->getOperand(0); SDValue Ops[] = { Val, getI32Imm(0), getI32Imm(MB), getI32Imm(ME) }; @@ -957,7 +957,7 @@ } // ISD::OR doesn't get all the bitfield insertion fun. // (and (or x, c1), c2) where isRunOfOnes(~(c1^c2)) is a bitfield insert - if (isInt32Immediate(N->getOperand(1), Imm) && + if (isInt32Immediate(N->getOperand(1), Imm) && N->getOperand(0).getOpcode() == ISD::OR && isInt32Immediate(N->getOperand(0).getOperand(1), Imm2)) { unsigned MB, ME; @@ -969,7 +969,7 @@ return CurDAG->getMachineNode(PPC::RLWIMI, dl, MVT::i32, Ops, 5); } } - + // Other cases are autogenerated. break; } @@ -977,7 +977,7 @@ if (N->getValueType(0) == MVT::i32) if (SDNode *I = SelectBitfieldInsert(N)) return I; - + // Other cases are autogenerated. break; case ISD::SHL: { @@ -988,25 +988,25 @@ getI32Imm(SH), getI32Imm(MB), getI32Imm(ME) }; return CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Ops, 4); } - + // Other cases are autogenerated. break; } case ISD::SRL: { unsigned Imm, SH, MB, ME; if (isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::AND, Imm) && - isRotateAndMask(N, Imm, true, SH, MB, ME)) { + isRotateAndMask(N, Imm, true, SH, MB, ME)) { SDValue Ops[] = { N->getOperand(0).getOperand(0), getI32Imm(SH), getI32Imm(MB), getI32Imm(ME) }; return CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Ops, 4); } - + // Other cases are autogenerated. break; } case ISD::SELECT_CC: { ISD::CondCode CC = cast(N->getOperand(4))->get(); - + // Handle the setcc cases here. select_cc lhs, 0, 1, 0, cc if (ConstantSDNode *N1C = dyn_cast(N->getOperand(1))) if (ConstantSDNode *N2C = dyn_cast(N->getOperand(2))) @@ -1058,7 +1058,7 @@ case ISD::BR_CC: { ISD::CondCode CC = cast(N->getOperand(1))->get(); SDValue CondCode = SelectCC(N->getOperand(2), N->getOperand(3), CC, dl); - SDValue Ops[] = { getI32Imm(getPredicateForSetCC(CC)), CondCode, + SDValue Ops[] = { getI32Imm(getPredicateForSetCC(CC)), CondCode, N->getOperand(4), N->getOperand(0) }; return CurDAG->SelectNodeTo(N, PPC::BCC, MVT::Other, Ops, 4); } @@ -1072,13 +1072,13 @@ return CurDAG->SelectNodeTo(N, PPC::BCTR, MVT::Other, Chain); } } - + return SelectCode(N); } -/// createPPCISelDag - This pass converts a legalized DAG into a +/// createPPCISelDag - This pass converts a legalized DAG into a /// PowerPC-specific DAG, ready for instruction scheduling. /// FunctionPass *llvm::createPPCISelDag(PPCTargetMachine &TM) { Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp?rev=122539&r1=122538&r2=122539&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp Thu Dec 23 22:28:06 2010 @@ -39,7 +39,7 @@ : TargetInstrInfoImpl(PPCInsts, array_lengthof(PPCInsts)), TM(tm), RI(*TM.getSubtargetImpl(), *this) {} -unsigned PPCInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, +unsigned PPCInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const { switch (MI->getOpcode()) { default: break; @@ -57,7 +57,7 @@ return 0; } -unsigned PPCInstrInfo::isStoreToStackSlot(const MachineInstr *MI, +unsigned PPCInstrInfo::isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const { switch (MI->getOpcode()) { default: break; @@ -84,11 +84,11 @@ // Normal instructions can be commuted the obvious way. if (MI->getOpcode() != PPC::RLWIMI) return TargetInstrInfoImpl::commuteInstruction(MI, NewMI); - + // Cannot commute if it has a non-zero rotate count. if (MI->getOperand(3).getImm() != 0) return 0; - + // If we have a zero rotate count, we have: // M = mask(MB,ME) // Op0 = (Op1 & ~M) | (Op2 & M) @@ -135,14 +135,14 @@ MI->getOperand(1).setReg(Reg2); MI->getOperand(2).setIsKill(Reg1IsKill); MI->getOperand(1).setIsKill(Reg2IsKill); - + // Swap the mask around. MI->getOperand(4).setImm((ME+1) & 31); MI->getOperand(5).setImm((MB-1) & 31); return MI; } -void PPCInstrInfo::insertNoop(MachineBasicBlock &MBB, +void PPCInstrInfo::insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const { DebugLoc DL; BuildMI(MBB, MI, DL, get(PPC::NOP)); @@ -169,7 +169,7 @@ // Get the last instruction in the block. MachineInstr *LastInst = I; - + // If there is only one terminator instruction, process it. if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { if (LastInst->getOpcode() == PPC::B) { @@ -189,7 +189,7 @@ // Otherwise, don't know what this is. return true; } - + // Get the instruction before it if it's a terminator. MachineInstr *SecondLastInst = I; @@ -197,9 +197,9 @@ if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I)) return true; - + // If the block ends with PPC::B and PPC:BCC, handle it. - if (SecondLastInst->getOpcode() == PPC::BCC && + if (SecondLastInst->getOpcode() == PPC::BCC && LastInst->getOpcode() == PPC::B) { if (!SecondLastInst->getOperand(2).isMBB() || !LastInst->getOperand(0).isMBB()) @@ -210,10 +210,10 @@ FBB = LastInst->getOperand(0).getMBB(); return false; } - + // If the block ends with two PPC:Bs, handle it. The second one is not // executed, so remove it. - if (SecondLastInst->getOpcode() == PPC::B && + if (SecondLastInst->getOpcode() == PPC::B && LastInst->getOpcode() == PPC::B) { if (!SecondLastInst->getOperand(0).isMBB()) return true; @@ -239,17 +239,17 @@ } if (I->getOpcode() != PPC::B && I->getOpcode() != PPC::BCC) return 0; - + // Remove the branch. I->eraseFromParent(); - + I = MBB.end(); if (I == MBB.begin()) return 1; --I; if (I->getOpcode() != PPC::BCC) return 1; - + // Remove the branch. I->eraseFromParent(); return 2; @@ -262,9 +262,9 @@ DebugLoc DL) const { // Shouldn't be a fall through. assert(TBB && "InsertBranch must not be told to insert a fallthrough"); - assert((Cond.size() == 2 || Cond.size() == 0) && + assert((Cond.size() == 2 || Cond.size() == 0) && "PPC branch conditions have two components!"); - + // One-way branch. if (FBB == 0) { if (Cond.empty()) // Unconditional branch @@ -274,7 +274,7 @@ .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB); return 1; } - + // Two-way Conditional Branch. BuildMI(&MBB, DL, get(PPC::BCC)) .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB); @@ -377,11 +377,11 @@ // We need to store the CR in the low 4-bits of the saved value. First, // issue a MFCR to save all of the CRBits. - unsigned ScratchReg = TM.getSubtargetImpl()->isDarwinABI() ? + unsigned ScratchReg = TM.getSubtargetImpl()->isDarwinABI() ? PPC::R2 : PPC::R0; NewMIs.push_back(BuildMI(MF, DL, get(PPC::MFCRpseud), ScratchReg) .addReg(SrcReg, getKillRegState(isKill))); - + // If the saved register wasn't CR0, shift the bits left so that they are // in CR0's slot. if (SrcReg != PPC::CR0) { @@ -391,7 +391,7 @@ .addReg(ScratchReg).addImm(ShiftBits) .addImm(0).addImm(31)); } - + NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STW)) .addReg(ScratchReg, getKillRegState(isKill)), @@ -428,14 +428,14 @@ SrcReg == PPC::CR7EQ || SrcReg == PPC::CR7UN) Reg = PPC::CR7; - return StoreRegToStackSlot(MF, Reg, isKill, FrameIdx, + return StoreRegToStackSlot(MF, Reg, isKill, FrameIdx, PPC::CRRCRegisterClass, NewMIs); } else if (RC == PPC::VRRCRegisterClass) { // We don't have indexed addressing for vector loads. Emit: // R0 = ADDI FI# // STVX VAL, 0, R0 - // + // // FIXME: We use R0 here, because it isn't available for RA. NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::ADDI), PPC::R0), FrameIdx, 0, 0)); @@ -514,9 +514,9 @@ // at the moment. unsigned ScratchReg = TM.getSubtargetImpl()->isDarwinABI() ? PPC::R2 : PPC::R0; - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LWZ), + NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LWZ), ScratchReg), FrameIdx)); - + // If the reloaded register isn't CR0, shift the bits right so that they are // in the right CR's slot. if (DestReg != PPC::CR0) { @@ -526,11 +526,11 @@ .addReg(ScratchReg).addImm(32-ShiftBits).addImm(0) .addImm(31)); } - + NewMIs.push_back(BuildMI(MF, DL, get(PPC::MTCRF), DestReg) .addReg(ScratchReg)); } else if (RC == PPC::CRBITRCRegisterClass) { - + unsigned Reg = 0; if (DestReg == PPC::CR0LT || DestReg == PPC::CR0GT || DestReg == PPC::CR0EQ || DestReg == PPC::CR0UN) @@ -557,14 +557,14 @@ DestReg == PPC::CR7EQ || DestReg == PPC::CR7UN) Reg = PPC::CR7; - return LoadRegFromStackSlot(MF, DL, Reg, FrameIdx, + return LoadRegFromStackSlot(MF, DL, Reg, FrameIdx, PPC::CRRCRegisterClass, NewMIs); } else if (RC == PPC::VRRCRegisterClass) { // We don't have indexed addressing for vector loads. Emit: // R0 = ADDI FI# // Dest = LVX 0, R0 - // + // // FIXME: We use R0 here, because it isn't available for RA. NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::ADDI), PPC::R0), FrameIdx, 0, 0)); Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h?rev=122539&r1=122538&r2=122539&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h (original) +++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h Thu Dec 23 22:28:06 2010 @@ -32,7 +32,7 @@ /// PPC970_First - This instruction starts a new dispatch group, so it will /// always be the first one in the group. PPC970_First = 0x1, - + /// PPC970_Single - This instruction starts a new dispatch group and /// terminates it, so it will be the sole instruction in the group. PPC970_Single = 0x2, @@ -40,7 +40,7 @@ /// PPC970_Cracked - This instruction is cracked into two pieces, requiring /// two dispatch pipes to be available to issue. PPC970_Cracked = 0x4, - + /// PPC970_Mask/Shift - This is a bitmask that selects the pipeline type that /// an instruction is issued to. PPC970_Shift = 3, @@ -59,8 +59,8 @@ PPC970_BRU = 7 << PPC970_Shift // Branch Unit }; } // end namespace PPCII - - + + class PPCInstrInfo : public TargetInstrInfoImpl { PPCTargetMachine &TM; const PPCRegisterInfo RI; @@ -69,7 +69,7 @@ unsigned SrcReg, bool isKill, int FrameIdx, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const; - void LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL, + void LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL, unsigned DestReg, int FrameIdx, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const; @@ -90,8 +90,8 @@ // commuteInstruction - We can commute rlwimi instructions, but only if the // rotate amt is zero. We also have to munge the immediates a bit. virtual MachineInstr *commuteInstruction(MachineInstr *MI, bool NewMI) const; - - virtual void insertNoop(MachineBasicBlock &MBB, + + virtual void insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const; @@ -109,7 +109,7 @@ MachineBasicBlock::iterator I, DebugLoc DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const; - + virtual void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool isKill, int FrameIndex, @@ -121,7 +121,7 @@ unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const; - + virtual MachineInstr *emitFrameIndexDebugValue(MachineFunction &MF, int FrameIx, uint64_t Offset, @@ -130,7 +130,7 @@ virtual bool ReverseBranchCondition(SmallVectorImpl &Cond) const; - + /// GetInstSize - Return the number of bytes of code the specified /// instruction may be. This returns the maximum number of bytes. /// Modified: llvm/trunk/lib/Target/TargetInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetInstrInfo.cpp?rev=122539&r1=122538&r2=122539&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/TargetInstrInfo.cpp Thu Dec 23 22:28:06 2010 @@ -128,7 +128,7 @@ /// insertNoop - Insert a noop into the instruction stream at the specified /// point. -void TargetInstrInfo::insertNoop(MachineBasicBlock &MBB, +void TargetInstrInfo::insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const { llvm_unreachable("Target didn't implement insertNoop!"); } @@ -137,7 +137,7 @@ bool TargetInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const { const TargetInstrDesc &TID = MI->getDesc(); if (!TID.isTerminator()) return false; - + // Conditional branch is a special case. if (TID.isBranch() && !TID.isBarrier()) return true; @@ -157,8 +157,8 @@ /// may be overloaded in the target code to do that. unsigned TargetInstrInfo::getInlineAsmLength(const char *Str, const MCAsmInfo &MAI) const { - - + + // Count the number of instructions in the asm. bool atInsnStart = true; unsigned Length = 0; @@ -173,6 +173,6 @@ strlen(MAI.getCommentString())) == 0) atInsnStart = false; } - + return Length; } From atrick at apple.com Thu Dec 23 23:03:26 2010 From: atrick at apple.com (Andrew Trick) Date: Fri, 24 Dec 2010 05:03:26 -0000 Subject: [llvm-commits] [llvm] r122541 - in /llvm/trunk: include/llvm/CodeGen/ include/llvm/Target/ lib/CodeGen/ lib/CodeGen/SelectionDAG/ lib/Target/ARM/ lib/Target/CellSPU/ lib/Target/PowerPC/ Message-ID: <20101224050326.B00E12A6C12C@llvm.org> Author: atrick Date: Thu Dec 23 23:03:26 2010 New Revision: 122541 URL: http://llvm.org/viewvc/llvm-project?rev=122541&view=rev Log: Various bits of framework needed for precise machine-level selection DAG scheduling during isel. Most new functionality is currently guarded by -enable-sched-cycles and -enable-sched-hazard. Added InstrItineraryData::IssueWidth field, currently derived from ARM itineraries, but could be initialized differently on other targets. Added ScheduleHazardRecognizer::MaxLookAhead to indicate whether it is active, and if so how many cycles of state it holds. Added SchedulingPriorityQueue::HasReadyFilter to allowing gating entry into the scheduler's available queue. ScoreboardHazardRecognizer now accesses the ScheduleDAG in order to get information about it's SUnits, provides RecedeCycle for bottom-up scheduling, correctly computes scoreboard depth, tracks IssueCount, and considers potential stall cycles when checking for hazards. ScheduleDAGRRList now models machine cycles and hazards (under flags). It tracks MinAvailableCycle, drives the hazard recognizer and priority queue's ready filter, manages a new PendingQueue, properly accounts for stall cycles, etc. Modified: llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h llvm/trunk/include/llvm/CodeGen/ScheduleHazardRecognizer.h llvm/trunk/include/llvm/CodeGen/ScoreboardHazardRecognizer.h llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h llvm/trunk/include/llvm/Target/TargetInstrInfo.h llvm/trunk/include/llvm/Target/TargetInstrItineraries.h llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp llvm/trunk/lib/CodeGen/ScheduleDAG.cpp llvm/trunk/lib/CodeGen/ScoreboardHazardRecognizer.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/trunk/lib/CodeGen/TargetInstrInfoImpl.cpp llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h llvm/trunk/lib/Target/ARM/ARMHazardRecognizer.cpp llvm/trunk/lib/Target/ARM/ARMHazardRecognizer.h llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp llvm/trunk/lib/Target/ARM/ARMSubtarget.h llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.cpp llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.h llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h Modified: llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h?rev=122541&r1=122540&r2=122541&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h (original) +++ llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h Thu Dec 23 23:03:26 2010 @@ -47,6 +47,8 @@ LatencyPriorityQueue() : Picker(this) { } + bool isBottomUp() const { return false; } + void initNodes(std::vector &sunits) { SUnits = &sunits; NumNodesSolelyBlocking.resize(SUnits->size(), 0); @@ -81,6 +83,8 @@ virtual void remove(SUnit *SU); + virtual void dump(ScheduleDAG* DAG) const; + // ScheduledNode - As nodes are scheduled, we look to see if there are any // successor nodes that have a single unscheduled predecessor. If so, that // single predecessor has a higher priority, since scheduling it will make Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=122541&r1=122540&r2=122541&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Thu Dec 23 23:03:26 2010 @@ -326,6 +326,10 @@ return Node; } + /// isInstr - Return true if this SUnit refers to a machine instruction as + /// opposed to an SDNode. + bool isInstr() const { return !Node; } + /// setInstr - Assign the instruction for the SUnit. /// This may be used during post-regalloc scheduling. void setInstr(MachineInstr *MI) { @@ -421,16 +425,27 @@ /// class SchedulingPriorityQueue { unsigned CurCycle; + bool HasReadyFilter; public: - SchedulingPriorityQueue() : CurCycle(0) {} + SchedulingPriorityQueue(bool rf = false): + CurCycle(0), HasReadyFilter(rf) {} virtual ~SchedulingPriorityQueue() {} + virtual bool isBottomUp() const = 0; + virtual void initNodes(std::vector &SUnits) = 0; virtual void addNode(const SUnit *SU) = 0; virtual void updateNode(const SUnit *SU) = 0; virtual void releaseState() = 0; virtual bool empty() const = 0; + + bool hasReadyFilter() const { return HasReadyFilter; } + + virtual bool isReady(SUnit *U) const { + assert(!HasReadyFilter && "The ready filter must override isReady()"); + return true; + } virtual void push(SUnit *U) = 0; void push_all(const std::vector &Nodes) { @@ -443,6 +458,8 @@ virtual void remove(SUnit *SU) = 0; + virtual void dump(ScheduleDAG *DAG) const {} + /// ScheduledNode - As each node is scheduled, this method is invoked. This /// allows the priority function to adjust the priority of related /// unscheduled nodes, for example. @@ -479,6 +496,13 @@ virtual ~ScheduleDAG(); + /// getInstrDesc - Return the TargetInstrDesc of this SUnit. + /// Return NULL for SDNodes without a machine opcode. + const TargetInstrDesc *getInstrDesc(const SUnit *SU) const { + if (SU->isInstr()) return &SU->getInstr()->getDesc(); + return getNodeDesc(SU->getNode()); + } + /// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered /// using 'dot'. /// @@ -542,6 +566,10 @@ void EmitNoop(); void EmitPhysRegCopy(SUnit *SU, DenseMap &VRBaseMap); + + private: + // Return the TargetInstrDesc of this SDNode or NULL. + const TargetInstrDesc *getNodeDesc(const SDNode *Node) const; }; class SUnitIterator : public std::iteratorgetHeight() << ": "; + su->dump(DAG); + } +} +#endif Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=122541&r1=122540&r2=122541&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Thu Dec 23 23:03:26 2010 @@ -133,18 +133,12 @@ std::vector KillIndices; public: - SchedulePostRATDList(MachineFunction &MF, - const MachineLoopInfo &MLI, - const MachineDominatorTree &MDT, - ScheduleHazardRecognizer *HR, - AntiDepBreaker *ADB, - AliasAnalysis *aa) - : ScheduleDAGInstrs(MF, MLI, MDT), Topo(SUnits), - HazardRec(HR), AntiDepBreak(ADB), AA(aa), - KillIndices(TRI->getNumRegs()) {} + SchedulePostRATDList( + MachineFunction &MF, MachineLoopInfo &MLI, MachineDominatorTree &MDT, + AliasAnalysis *AA, TargetSubtarget::AntiDepBreakMode AntiDepMode, + SmallVectorImpl &CriticalPathRCs); - ~SchedulePostRATDList() { - } + ~SchedulePostRATDList(); /// StartBlock - Initialize register live-range state for scheduling in /// this block. @@ -183,9 +177,34 @@ }; } +SchedulePostRATDList::SchedulePostRATDList( + MachineFunction &MF, MachineLoopInfo &MLI, MachineDominatorTree &MDT, + AliasAnalysis *AA, TargetSubtarget::AntiDepBreakMode AntiDepMode, + SmallVectorImpl &CriticalPathRCs) + : ScheduleDAGInstrs(MF, MLI, MDT), Topo(SUnits), AA(AA), + KillIndices(TRI->getNumRegs()) +{ + const TargetMachine &TM = MF.getTarget(); + const InstrItineraryData *InstrItins = TM.getInstrItineraryData(); + HazardRec = + TM.getInstrInfo()->CreateTargetPostRAHazardRecognizer(InstrItins, this); + AntiDepBreak = + ((AntiDepMode == TargetSubtarget::ANTIDEP_ALL) ? + (AntiDepBreaker *)new AggressiveAntiDepBreaker(MF, CriticalPathRCs) : + ((AntiDepMode == TargetSubtarget::ANTIDEP_CRITICAL) ? + (AntiDepBreaker *)new CriticalAntiDepBreaker(MF) : NULL)); +} + +SchedulePostRATDList::~SchedulePostRATDList() { + delete HazardRec; + delete AntiDepBreak; +} + bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) { - AA = &getAnalysis(); TII = Fn.getTarget().getInstrInfo(); + MachineLoopInfo &MLI = getAnalysis(); + MachineDominatorTree &MDT = getAnalysis(); + AliasAnalysis *AA = &getAnalysis(); // Check for explicit enable/disable of post-ra scheduling. TargetSubtarget::AntiDepBreakMode AntiDepMode = TargetSubtarget::ANTIDEP_NONE; @@ -195,6 +214,7 @@ return false; } else { // Check that post-RA scheduling is enabled for this target. + // This may upgrade the AntiDepMode. const TargetSubtarget &ST = Fn.getTarget().getSubtarget(); if (!ST.enablePostRAScheduler(OptLevel, AntiDepMode, CriticalPathRCs)) return false; @@ -210,19 +230,8 @@ DEBUG(dbgs() << "PostRAScheduler\n"); - const MachineLoopInfo &MLI = getAnalysis(); - const MachineDominatorTree &MDT = getAnalysis(); - const TargetMachine &TM = Fn.getTarget(); - const InstrItineraryData *InstrItins = TM.getInstrItineraryData(); - ScheduleHazardRecognizer *HR = - TM.getInstrInfo()->CreateTargetPostRAHazardRecognizer(InstrItins); - AntiDepBreaker *ADB = - ((AntiDepMode == TargetSubtarget::ANTIDEP_ALL) ? - (AntiDepBreaker *)new AggressiveAntiDepBreaker(Fn, CriticalPathRCs) : - ((AntiDepMode == TargetSubtarget::ANTIDEP_CRITICAL) ? - (AntiDepBreaker *)new CriticalAntiDepBreaker(Fn) : NULL)); - - SchedulePostRATDList Scheduler(Fn, MLI, MDT, HR, ADB, AA); + SchedulePostRATDList Scheduler(Fn, MLI, MDT, AA, AntiDepMode, + CriticalPathRCs); // Loop over all of the basic blocks for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); @@ -270,9 +279,6 @@ Scheduler.FixupKills(MBB); } - delete HR; - delete ADB; - return true; } @@ -617,13 +623,7 @@ MinDepth = PendingQueue[i]->getDepth(); } - DEBUG(dbgs() << "\n*** Examining Available\n"; - LatencyPriorityQueue q = AvailableQueue; - while (!q.empty()) { - SUnit *su = q.pop(); - dbgs() << "Height " << su->getHeight() << ": "; - su->dump(this); - }); + DEBUG(dbgs() << "\n*** Examining Available\n"; AvailableQueue.dump(this)); SUnit *FoundSUnit = 0; bool HasNoopHazards = false; @@ -631,7 +631,7 @@ SUnit *CurSUnit = AvailableQueue.pop(); ScheduleHazardRecognizer::HazardType HT = - HazardRec->getHazardType(CurSUnit); + HazardRec->getHazardType(CurSUnit, 0/*no stalls*/); if (HT == ScheduleHazardRecognizer::NoHazard) { FoundSUnit = CurSUnit; break; Modified: llvm/trunk/lib/CodeGen/ScheduleDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAG.cpp?rev=122541&r1=122540&r2=122541&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ScheduleDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/ScheduleDAG.cpp Thu Dec 23 23:03:26 2010 @@ -15,6 +15,7 @@ #define DEBUG_TYPE "pre-RA-sched" #include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/CodeGen/ScheduleHazardRecognizer.h" +#include "llvm/CodeGen/SelectionDAGNodes.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetRegisterInfo.h" @@ -33,6 +34,12 @@ ScheduleDAG::~ScheduleDAG() {} +/// getInstrDesc helper to handle SDNodes. +const TargetInstrDesc *ScheduleDAG::getNodeDesc(const SDNode *Node) const { + if (!Node->isMachineOpcode()) return NULL; + return &TII->get(Node->getMachineOpcode()); +} + /// dump - dump the schedule. void ScheduleDAG::dumpSchedule() const { for (unsigned i = 0, e = Sequence.size(); i != e; i++) { Modified: llvm/trunk/lib/CodeGen/ScoreboardHazardRecognizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScoreboardHazardRecognizer.cpp?rev=122541&r1=122540&r2=122541&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ScoreboardHazardRecognizer.cpp (original) +++ llvm/trunk/lib/CodeGen/ScoreboardHazardRecognizer.cpp Thu Dec 23 23:03:26 2010 @@ -13,7 +13,7 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "sched-hazard" +#define DEBUG_TYPE ::llvm::ScoreboardHazardRecognizer::DebugType #include "llvm/CodeGen/ScoreboardHazardRecognizer.h" #include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/Support/Debug.h" @@ -23,29 +23,48 @@ using namespace llvm; +#ifndef NDEBUG +const char *ScoreboardHazardRecognizer::DebugType = ""; +#endif + ScoreboardHazardRecognizer:: -ScoreboardHazardRecognizer(const InstrItineraryData *LItinData) : - ScheduleHazardRecognizer(), ItinData(LItinData) { +ScoreboardHazardRecognizer(const InstrItineraryData *II, + const ScheduleDAG *SchedDAG, + const char *ParentDebugType) : + ScheduleHazardRecognizer(), ItinData(II), DAG(SchedDAG), IssueWidth(0), + IssueCount(0) { + +#ifndef NDEBUG + DebugType = ParentDebugType; +#endif + // Determine the maximum depth of any itinerary. This determines the // depth of the scoreboard. We always make the scoreboard at least 1 // cycle deep to avoid dealing with the boundary condition. unsigned ScoreboardDepth = 1; if (ItinData && !ItinData->isEmpty()) { + IssueWidth = ItinData->IssueWidth; + for (unsigned idx = 0; ; ++idx) { if (ItinData->isEndMarker(idx)) break; const InstrStage *IS = ItinData->beginStage(idx); const InstrStage *E = ItinData->endStage(idx); + unsigned CurCycle = 0; unsigned ItinDepth = 0; - for (; IS != E; ++IS) - ItinDepth += IS->getCycles(); + for (; IS != E; ++IS) { + unsigned StageDepth = CurCycle + IS->getCycles(); + if (ItinDepth < StageDepth) ItinDepth = StageDepth; + CurCycle += IS->getNextCycles(); + } // Find the next power-of-2 >= ItinDepth while (ItinDepth > ScoreboardDepth) { ScoreboardDepth *= 2; } } + MaxLookAhead = ScoreboardDepth; } ReservedScoreboard.reset(ScoreboardDepth); @@ -56,6 +75,7 @@ } void ScoreboardHazardRecognizer::Reset() { + IssueCount = 0; RequiredScoreboard.reset(); ReservedScoreboard.reset(); } @@ -76,24 +96,46 @@ } } +bool ScoreboardHazardRecognizer::atIssueLimit() const { + if (IssueWidth == 0) + return false; + + return IssueCount == IssueWidth; +} + ScheduleHazardRecognizer::HazardType -ScoreboardHazardRecognizer::getHazardType(SUnit *SU) { +ScoreboardHazardRecognizer::getHazardType(SUnit *SU, int Stalls) { if (!ItinData || ItinData->isEmpty()) return NoHazard; - unsigned cycle = 0; + // Note that stalls will be negative for bottom-up scheduling. + int cycle = Stalls; // Use the itinerary for the underlying instruction to check for // free FU's in the scoreboard at the appropriate future cycles. - unsigned idx = SU->getInstr()->getDesc().getSchedClass(); + + const TargetInstrDesc *TID = DAG->getInstrDesc(SU); + if (TID == NULL) { + // Don't check hazards for non-machineinstr Nodes. + return NoHazard; + } + unsigned idx = TID->getSchedClass(); for (const InstrStage *IS = ItinData->beginStage(idx), *E = ItinData->endStage(idx); IS != E; ++IS) { // We must find one of the stage's units free for every cycle the // stage is occupied. FIXME it would be more accurate to find the // same unit free in all the cycles. for (unsigned int i = 0; i < IS->getCycles(); ++i) { - assert(((cycle + i) < RequiredScoreboard.getDepth()) && - "Scoreboard depth exceeded!"); + int StageCycle = cycle + (int)i; + if (StageCycle < 0) + continue; + + if (StageCycle >= (int)RequiredScoreboard.getDepth()) { + assert((StageCycle - Stalls) < (int)RequiredScoreboard.getDepth() && + "Scoreboard depth exceeded!"); + // This stage was stalled beyond pipeline depth, so cannot conflict. + break; + } unsigned freeUnits = IS->getUnits(); switch (IS->getReservationKind()) { @@ -101,18 +143,18 @@ assert(0 && "Invalid FU reservation"); case InstrStage::Required: // Required FUs conflict with both reserved and required ones - freeUnits &= ~ReservedScoreboard[cycle + i]; + freeUnits &= ~ReservedScoreboard[StageCycle]; // FALLTHROUGH case InstrStage::Reserved: // Reserved FUs can conflict only with required ones. - freeUnits &= ~RequiredScoreboard[cycle + i]; + freeUnits &= ~RequiredScoreboard[StageCycle]; break; } if (!freeUnits) { DEBUG(dbgs() << "*** Hazard in cycle " << (cycle + i) << ", "); DEBUG(dbgs() << "SU(" << SU->NodeNum << "): "); - DEBUG(SU->getInstr()->dump()); + DEBUG(DAG->dumpNode(SU)); return Hazard; } } @@ -128,11 +170,15 @@ if (!ItinData || ItinData->isEmpty()) return; + ++IssueCount; + unsigned cycle = 0; // Use the itinerary for the underlying instruction to reserve FU's // in the scoreboard at the appropriate future cycles. - unsigned idx = SU->getInstr()->getDesc().getSchedClass(); + const TargetInstrDesc *TID = DAG->getInstrDesc(SU); + assert(TID && "The scheduler must filter non-machineinstrs"); + unsigned idx = TID->getSchedClass(); for (const InstrStage *IS = ItinData->beginStage(idx), *E = ItinData->endStage(idx); IS != E; ++IS) { // We must reserve one of the stage's units for every cycle the @@ -179,11 +225,13 @@ } void ScoreboardHazardRecognizer::AdvanceCycle() { + IssueCount = 0; ReservedScoreboard[0] = 0; ReservedScoreboard.advance(); RequiredScoreboard[0] = 0; RequiredScoreboard.advance(); } void ScoreboardHazardRecognizer::RecedeCycle() { + IssueCount = 0; ReservedScoreboard[ReservedScoreboard.getDepth()-1] = 0; ReservedScoreboard.recede(); RequiredScoreboard[RequiredScoreboard.getDepth()-1] = 0; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp?rev=122541&r1=122540&r2=122541&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Thu Dec 23 23:03:26 2010 @@ -63,11 +63,12 @@ public: ScheduleDAGList(MachineFunction &mf, - SchedulingPriorityQueue *availqueue, - ScheduleHazardRecognizer *HR) - : ScheduleDAGSDNodes(mf), - AvailableQueue(availqueue), HazardRec(HR) { - } + SchedulingPriorityQueue *availqueue) + : ScheduleDAGSDNodes(mf), AvailableQueue(availqueue) { + + const TargetMachine &tm = mf.getTarget(); + HazardRec = tm.getInstrInfo()->CreateTargetHazardRecognizer(&tm, this); + } ~ScheduleDAGList() { delete HazardRec; @@ -202,7 +203,7 @@ SUnit *CurSUnit = AvailableQueue->pop(); ScheduleHazardRecognizer::HazardType HT = - HazardRec->getHazardType(CurSUnit); + HazardRec->getHazardType(CurSUnit, 0/*no stalls*/); if (HT == ScheduleHazardRecognizer::NoHazard) { FoundSUnit = CurSUnit; break; @@ -257,12 +258,8 @@ // Public Constructor Functions //===----------------------------------------------------------------------===// -/// createTDListDAGScheduler - This creates a top-down list scheduler with a -/// new hazard recognizer. This scheduler takes ownership of the hazard -/// recognizer and deletes it when done. +/// createTDListDAGScheduler - This creates a top-down list scheduler. ScheduleDAGSDNodes * llvm::createTDListDAGScheduler(SelectionDAGISel *IS, CodeGenOpt::Level) { - return new ScheduleDAGList(*IS->MF, - new LatencyPriorityQueue(), - IS->CreateTargetHazardRecognizer()); + return new ScheduleDAGList(*IS->MF, new LatencyPriorityQueue()); } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=122541&r1=122540&r2=122541&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Thu Dec 23 23:03:26 2010 @@ -20,6 +20,7 @@ #include "llvm/InlineAsm.h" #include "llvm/CodeGen/SchedulerRegistry.h" #include "llvm/CodeGen/SelectionDAGISel.h" +#include "llvm/CodeGen/ScheduleHazardRecognizer.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" @@ -65,6 +66,11 @@ "which tries to balance ILP and register pressure", createILPListDAGScheduler); +static cl::opt EnableSchedCycles( + "enable-sched-cycles", + cl::desc("Enable cycle-level precision during preRA scheduling"), + cl::init(false), cl::Hidden); + namespace { //===----------------------------------------------------------------------===// /// ScheduleDAGRRList - The actual register reduction list scheduler @@ -83,9 +89,21 @@ /// AvailableQueue - The priority queue to use for the available SUnits. SchedulingPriorityQueue *AvailableQueue; + /// PendingQueue - This contains all of the instructions whose operands have + /// been issued, but their results are not ready yet (due to the latency of + /// the operation). Once the operands becomes available, the instruction is + /// added to the AvailableQueue. + std::vector PendingQueue; + + /// HazardRec - The hazard recognizer to use. + ScheduleHazardRecognizer *HazardRec; + /// CurCycle - The current scheduler state corresponds to this cycle. unsigned CurCycle; + /// MinAvailableCycle - Cycle of the soonest available instruction. + unsigned MinAvailableCycle; + /// 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. @@ -98,14 +116,22 @@ ScheduleDAGTopologicalSort Topo; public: - ScheduleDAGRRList(MachineFunction &mf, - bool isbottomup, bool needlatency, - SchedulingPriorityQueue *availqueue) - : ScheduleDAGSDNodes(mf), isBottomUp(isbottomup), NeedLatency(needlatency), - AvailableQueue(availqueue), CurCycle(0), Topo(SUnits) { - } + ScheduleDAGRRList(MachineFunction &mf, bool needlatency, + SchedulingPriorityQueue *availqueue, + CodeGenOpt::Level OptLevel) + : ScheduleDAGSDNodes(mf), isBottomUp(availqueue->isBottomUp()), + NeedLatency(needlatency), AvailableQueue(availqueue), CurCycle(0), + Topo(SUnits) { + + const TargetMachine &tm = mf.getTarget(); + if (EnableSchedCycles && OptLevel != CodeGenOpt::None) + HazardRec = tm.getInstrInfo()->CreateTargetHazardRecognizer(&tm, this); + else + HazardRec = new ScheduleHazardRecognizer(); + } ~ScheduleDAGRRList() { + delete HazardRec; delete AvailableQueue; } @@ -139,20 +165,31 @@ } private: + bool isReady(SUnit *SU) { + return !EnableSchedCycles || !AvailableQueue->hasReadyFilter() || + AvailableQueue->isReady(SU); + } + void ReleasePred(SUnit *SU, const SDep *PredEdge); void ReleasePredecessors(SUnit *SU); void ReleaseSucc(SUnit *SU, const SDep *SuccEdge); void ReleaseSuccessors(SUnit *SU); - void CapturePred(SDep *PredEdge); + void ReleasePending(); + void AdvanceToCycle(unsigned NextCycle); + void AdvancePastStalls(SUnit *SU); + void EmitNode(SUnit *SU); void ScheduleNodeBottomUp(SUnit*); + void CapturePred(SDep *PredEdge); void UnscheduleNodeBottomUp(SUnit*); - void BacktrackBottomUp(SUnit*, unsigned); + void RestoreHazardCheckerBottomUp(); + void BacktrackBottomUp(SUnit*, SUnit*); SUnit *CopyAndMoveSuccessors(SUnit*); void InsertCopiesAndMoveSuccs(SUnit*, unsigned, const TargetRegisterClass*, const TargetRegisterClass*, SmallVector&); bool DelayForLiveRegsBottomUp(SUnit*, SmallVector&); + SUnit *PickNodeToScheduleBottomUp(); void ListScheduleBottomUp(); @@ -198,6 +235,7 @@ << " '" << BB->getName() << "' **********\n"); CurCycle = 0; + MinAvailableCycle = EnableSchedCycles ? UINT_MAX : 0; NumLiveRegs = 0; LiveRegDefs.resize(TRI->getNumRegs(), NULL); LiveRegGens.resize(TRI->getNumRegs(), NULL); @@ -211,6 +249,8 @@ AvailableQueue->initNodes(SUnits); + HazardRec->Reset(); + // Execute the actual scheduling loop Top-Down or Bottom-Up as appropriate. if (isBottomUp) ListScheduleBottomUp(); @@ -249,7 +289,20 @@ // to be scheduled. Ignore the special EntrySU node. if (PredSU->NumSuccsLeft == 0 && PredSU != &EntrySU) { PredSU->isAvailable = true; - AvailableQueue->push(PredSU); + + unsigned Height = PredSU->getHeight(); + if (Height < MinAvailableCycle) + MinAvailableCycle = Height; + + if (isReady(SU)) { + AvailableQueue->push(PredSU); + } + // CapturePred and others may have left the node in the pending queue, avoid + // adding it twice. + else if (!PredSU->isPending) { + PredSU->isPending = true; + PendingQueue.push_back(PredSU); + } } } @@ -292,6 +345,127 @@ } } +/// Check to see if any of the pending instructions are ready to issue. If +/// so, add them to the available queue. +void ScheduleDAGRRList::ReleasePending() { + assert(!EnableSchedCycles && "requires --enable-sched-cycles" ); + + // If the available queue is empty, it is safe to reset MinAvailableCycle. + if (AvailableQueue->empty()) + MinAvailableCycle = UINT_MAX; + + // Check to see if any of the pending instructions are ready to issue. If + // so, add them to the available queue. + for (unsigned i = 0, e = PendingQueue.size(); i != e; ++i) { + unsigned ReadyCycle = + isBottomUp ? PendingQueue[i]->getHeight() : PendingQueue[i]->getDepth(); + if (ReadyCycle < MinAvailableCycle) + MinAvailableCycle = ReadyCycle; + + if (PendingQueue[i]->isAvailable) { + if (!isReady(PendingQueue[i])) + continue; + AvailableQueue->push(PendingQueue[i]); + } + PendingQueue[i]->isPending = false; + PendingQueue[i] = PendingQueue.back(); + PendingQueue.pop_back(); + --i; --e; + } +} + +/// Move the scheduler state forward by the specified number of Cycles. +void ScheduleDAGRRList::AdvanceToCycle(unsigned NextCycle) { + if (NextCycle <= CurCycle) + return; + + AvailableQueue->setCurCycle(NextCycle); + if (HazardRec->getMaxLookAhead() == 0) { + // Bypass lots of virtual calls in case of long latency. + CurCycle = NextCycle; + } + else { + for (; CurCycle != NextCycle; ++CurCycle) { + if (isBottomUp) + HazardRec->RecedeCycle(); + else + HazardRec->AdvanceCycle(); + } + } + // FIXME: Instead of visiting the pending Q each time, set a dirty flag on the + // available Q to release pending nodes at least once before popping. + ReleasePending(); +} + +/// Move the scheduler state forward until the specified node's dependents are +/// ready and can be scheduled with no resource conflicts. +void ScheduleDAGRRList::AdvancePastStalls(SUnit *SU) { + if (!EnableSchedCycles) + return; + + unsigned ReadyCycle = isBottomUp ? SU->getHeight() : SU->getDepth(); + + // Bump CurCycle to account for latency. We assume the latency of other + // available instructions may be hidden by the stall (not a full pipe stall). + // This updates the hazard recognizer's cycle before reserving resources for + // this instruction. + AdvanceToCycle(ReadyCycle); + + // Calls are scheduled in their preceding cycle, so don't conflict with + // hazards from instructions after the call. EmitNode will reset the + // scoreboard state before emitting the call. + if (isBottomUp && SU->isCall) + return; + + // FIXME: For resource conflicts in very long non-pipelined stages, we + // should probably skip ahead here to avoid useless scoreboard checks. + int Stalls = 0; + while (true) { + ScheduleHazardRecognizer::HazardType HT = + HazardRec->getHazardType(SU, isBottomUp ? -Stalls : Stalls); + + if (HT == ScheduleHazardRecognizer::NoHazard) + break; + + ++Stalls; + } + AdvanceToCycle(CurCycle + Stalls); +} + +/// Record this SUnit in the HazardRecognizer. +/// Does not update CurCycle. +void ScheduleDAGRRList::EmitNode(SUnit *SU) { + switch (SU->getNode()->getOpcode()) { + default: + assert(SU->getNode()->isMachineOpcode() && + "This target-independent node should not be scheduled."); + break; + case ISD::MERGE_VALUES: + case ISD::TokenFactor: + case ISD::CopyToReg: + case ISD::CopyFromReg: + case ISD::EH_LABEL: + // Noops don't affect the scoreboard state. Copies are likely to be + // removed. + return; + case ISD::INLINEASM: + // For inline asm, clear the pipeline state. + HazardRec->Reset(); + return; + } + if (isBottomUp && SU->isCall) { + // Calls are scheduled with their preceding instructions. For bottom-up + // scheduling, clear the pipeline state before emitting. + HazardRec->Reset(); + } + + HazardRec->EmitInstruction(SU); + + if (!isBottomUp && SU->isCall) { + HazardRec->Reset(); + } +} + /// 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. @@ -304,8 +478,15 @@ DEBUG(dbgs() << " Height [" << SU->getHeight() << "] pipeline stall!\n"); #endif - // FIXME: Handle noop hazard. + // FIXME: Do not modify node height. It may interfere with + // backtracking. Instead add a "ready cycle" to SUnit. Before scheduling the + // node it's ready cycle can aid heuristics, and after scheduling it can + // indicate the scheduled cycle. SU->setHeightToAtLeast(CurCycle); + + // Reserve resources for the scheduled intruction. + EmitNode(SU); + Sequence.push_back(SU); AvailableQueue->ScheduledNode(SU); @@ -327,6 +508,15 @@ } SU->isScheduled = true; + + // Conditions under which the scheduler should eagerly advance the cycle: + // (1) No available instructions + // (2) All pipelines full, so available instructions must have hazards. + // + // If SchedCycles is disabled, count each inst as one cycle. + if (!EnableSchedCycles || + AvailableQueue->empty() || HazardRec->atIssueLimit()) + AdvanceToCycle(CurCycle + 1); } /// CapturePred - This does the opposite of ReleasePred. Since SU is being @@ -377,31 +567,69 @@ LiveRegGens[I->getReg()] = I->getSUnit(); } } + if (SU->getHeight() < MinAvailableCycle) + MinAvailableCycle = SU->getHeight(); SU->setHeightDirty(); SU->isScheduled = false; SU->isAvailable = true; - AvailableQueue->push(SU); + if (EnableSchedCycles && AvailableQueue->hasReadyFilter()) { + // Don't make available until backtracking is complete. + SU->isPending = true; + PendingQueue.push_back(SU); + } + else { + AvailableQueue->push(SU); + } AvailableQueue->UnscheduledNode(SU); } +/// After backtracking, the hazard checker needs to be restored to a state +/// corresponding the the current cycle. +void ScheduleDAGRRList::RestoreHazardCheckerBottomUp() { + HazardRec->Reset(); + + unsigned LookAhead = std::min((unsigned)Sequence.size(), + HazardRec->getMaxLookAhead()); + if (LookAhead == 0) + return; + + std::vector::const_iterator I = (Sequence.end() - LookAhead); + unsigned HazardCycle = (*I)->getHeight(); + for (std::vector::const_iterator E = Sequence.end(); I != E; ++I) { + SUnit *SU = *I; + for (; SU->getHeight() > HazardCycle; ++HazardCycle) { + HazardRec->RecedeCycle(); + } + EmitNode(SU); + } +} + /// BacktrackBottomUp - Backtrack scheduling to a previous cycle specified in /// BTCycle in order to schedule a specific node. -void ScheduleDAGRRList::BacktrackBottomUp(SUnit *SU, unsigned BtCycle) { - SUnit *OldSU = NULL; - while (CurCycle > BtCycle) { - OldSU = Sequence.back(); +void ScheduleDAGRRList::BacktrackBottomUp(SUnit *SU, SUnit *BtSU) { + SUnit *OldSU = Sequence.back(); + while (true) { Sequence.pop_back(); if (SU->isSucc(OldSU)) // Don't try to remove SU from AvailableQueue. SU->isAvailable = false; + // FIXME: use ready cycle instead of height + CurCycle = OldSU->getHeight(); UnscheduleNodeBottomUp(OldSU); - --CurCycle; AvailableQueue->setCurCycle(CurCycle); + if (OldSU == BtSU) + break; + OldSU = Sequence.back(); } assert(!SU->isSucc(OldSU) && "Something is wrong!"); + RestoreHazardCheckerBottomUp(); + + if (EnableSchedCycles) + ReleasePending(); + ++NumBacktracks; } @@ -741,7 +969,7 @@ /// Return a node that can be scheduled in this cycle. Requirements: /// (1) Ready: latency has been satisfied -/// (2) No Hazards: resources are available (TBD) +/// (2) No Hazards: resources are available /// (3) No Interferences: may unschedule to break register interferences. SUnit *ScheduleDAGRRList::PickNodeToScheduleBottomUp() { SmallVector Interferences; @@ -777,24 +1005,26 @@ // Try unscheduling up to the point where it's safe to schedule // this node. - unsigned LiveCycle = CurCycle; + SUnit *BtSU = NULL; + unsigned LiveCycle = UINT_MAX; for (unsigned j = 0, ee = LRegs.size(); j != ee; ++j) { unsigned Reg = LRegs[j]; - unsigned LCycle = LiveRegGens[Reg]->getHeight(); - LiveCycle = std::min(LiveCycle, LCycle); + if (LiveRegGens[Reg]->getHeight() < LiveCycle) { + BtSU = LiveRegGens[Reg]; + LiveCycle = BtSU->getHeight(); + } } - SUnit *OldSU = Sequence[LiveCycle]; - if (!WillCreateCycle(TrySU, OldSU)) { - BacktrackBottomUp(TrySU, LiveCycle); + if (!WillCreateCycle(TrySU, BtSU)) { + BacktrackBottomUp(TrySU, BtSU); // 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); + if (BtSU->isAvailable) { + BtSU->isAvailable = false; + if (!BtSU->isPending) + AvailableQueue->remove(BtSU); } - AddPred(TrySU, SDep(OldSU, SDep::Order, /*Latency=*/1, + AddPred(TrySU, SDep(BtSU, SDep::Order, /*Latency=*/1, /*Reg=*/0, /*isNormalMemory=*/false, /*isMustAlias=*/false, /*isArtificial=*/true)); @@ -891,15 +1121,22 @@ // priority. If it is not ready put it back. Schedule the node. Sequence.reserve(SUnits.size()); while (!AvailableQueue->empty()) { + DEBUG(dbgs() << "\n*** Examining Available\n"; + AvailableQueue->dump(this)); + // Pick the best node to schedule taking all constraints into // consideration. SUnit *SU = PickNodeToScheduleBottomUp(); - if (SU) - ScheduleNodeBottomUp(SU); + AdvancePastStalls(SU); - ++CurCycle; - AvailableQueue->setCurCycle(CurCycle); + ScheduleNodeBottomUp(SU); + + while (AvailableQueue->empty() && !PendingQueue.empty()) { + // Advance the cycle to free resources. Skip ahead to the next ready SU. + assert(MinAvailableCycle < UINT_MAX && "MinAvailableCycle uninitialized"); + AdvanceToCycle(std::max(CurCycle + 1, MinAvailableCycle)); + } } // Reverse the order if it is bottom up. @@ -967,7 +1204,6 @@ /// ListScheduleTopDown - The main loop of list scheduling for top-down /// schedulers. void ScheduleDAGRRList::ListScheduleTopDown() { - unsigned CurCycle = 0; AvailableQueue->setCurCycle(CurCycle); // Release any successors of the special Entry node. @@ -1011,9 +1247,18 @@ template class RegReductionPriorityQueue; + struct queue_sort : public std::binary_function { + bool isReady(SUnit* SU, unsigned CurCycle) const { return true; } + }; + /// bu_ls_rr_sort - Priority function for bottom up register pressure // reduction scheduler. - struct bu_ls_rr_sort : public std::binary_function { + struct bu_ls_rr_sort : public queue_sort { + enum { + IsBottomUp = true, + HasReadyFilter = false + }; + RegReductionPriorityQueue *SPQ; bu_ls_rr_sort(RegReductionPriorityQueue *spq) : SPQ(spq) {} bu_ls_rr_sort(const bu_ls_rr_sort &RHS) : SPQ(RHS.SPQ) {} @@ -1023,8 +1268,13 @@ // td_ls_rr_sort - Priority function for top down register pressure reduction // scheduler. - struct td_ls_rr_sort : public std::binary_function { - RegReductionPriorityQueue *SPQ; + struct td_ls_rr_sort : public queue_sort { + enum { + IsBottomUp = false, + HasReadyFilter = false + }; + + RegReductionPriorityQueue *SPQ; td_ls_rr_sort(RegReductionPriorityQueue *spq) : SPQ(spq) {} td_ls_rr_sort(const td_ls_rr_sort &RHS) : SPQ(RHS.SPQ) {} @@ -1032,7 +1282,12 @@ }; // src_ls_rr_sort - Priority function for source order scheduler. - struct src_ls_rr_sort : public std::binary_function { + struct src_ls_rr_sort : public queue_sort { + enum { + IsBottomUp = true, + HasReadyFilter = false + }; + RegReductionPriorityQueue *SPQ; src_ls_rr_sort(RegReductionPriorityQueue *spq) : SPQ(spq) {} @@ -1043,7 +1298,12 @@ }; // hybrid_ls_rr_sort - Priority function for hybrid scheduler. - struct hybrid_ls_rr_sort : public std::binary_function { + struct hybrid_ls_rr_sort : public queue_sort { + enum { + IsBottomUp = true, + HasReadyFilter = false + }; + RegReductionPriorityQueue *SPQ; hybrid_ls_rr_sort(RegReductionPriorityQueue *spq) : SPQ(spq) {} @@ -1055,13 +1315,20 @@ // ilp_ls_rr_sort - Priority function for ILP (instruction level parallelism) // scheduler. - struct ilp_ls_rr_sort : public std::binary_function { + struct ilp_ls_rr_sort : public queue_sort { + enum { + IsBottomUp = true, + HasReadyFilter = true + }; + RegReductionPriorityQueue *SPQ; ilp_ls_rr_sort(RegReductionPriorityQueue *spq) : SPQ(spq) {} ilp_ls_rr_sort(const ilp_ls_rr_sort &RHS) : SPQ(RHS.SPQ) {} + bool isReady(SUnit *SU, unsigned CurCycle) const; + bool operator()(const SUnit* left, const SUnit* right) const; }; } // end anonymous namespace @@ -1098,6 +1365,19 @@ namespace { template class RegReductionPriorityQueue : public SchedulingPriorityQueue { + static SUnit *popFromQueue(std::vector &Q, SF &Picker) { + std::vector::iterator Best = Q.begin(); + for (std::vector::iterator I = llvm::next(Q.begin()), + E = Q.end(); I != E; ++I) + if (Picker(*Best, *I)) + Best = I; + SUnit *V = *Best; + if (Best != prior(Q.end())) + std::swap(*Best, Q.back()); + Q.pop_back(); + return V; + } + std::vector Queue; SF Picker; unsigned CurQueueId; @@ -1130,7 +1410,8 @@ const TargetInstrInfo *tii, const TargetRegisterInfo *tri, const TargetLowering *tli) - : Picker(this), CurQueueId(0), TracksRegPressure(tracksrp), + : SchedulingPriorityQueue(SF::HasReadyFilter), Picker(this), + CurQueueId(0), TracksRegPressure(tracksrp), MF(mf), TII(tii), TRI(tri), TLI(tli), scheduleDAG(NULL) { if (TracksRegPressure) { unsigned NumRC = TRI->getNumRegClasses(); @@ -1144,6 +1425,8 @@ } } + bool isBottomUp() const { return SF::IsBottomUp; } + void initNodes(std::vector &sunits) { SUnits = &sunits; // Add pseudo dependency edges for two-address nodes. @@ -1205,6 +1488,10 @@ bool empty() const { return Queue.empty(); } + bool isReady(SUnit *U) const { + return Picker.HasReadyFilter && Picker.isReady(U, getCurCycle()); + } + void push(SUnit *U) { assert(!U->NodeQueueId && "Node in the queue already"); U->NodeQueueId = ++CurQueueId; @@ -1212,16 +1499,9 @@ } SUnit *pop() { - if (empty()) return NULL; - std::vector::iterator Best = Queue.begin(); - for (std::vector::iterator I = llvm::next(Queue.begin()), - E = Queue.end(); I != E; ++I) - if (Picker(*Best, *I)) - Best = I; - SUnit *V = *Best; - if (Best != prior(Queue.end())) - std::swap(*Best, Queue.back()); - Queue.pop_back(); + if (Queue.empty()) return NULL; + + SUnit *V = popFromQueue(Queue, Picker); V->NodeQueueId = 0; return V; } @@ -1475,6 +1755,20 @@ } } + void dump(ScheduleDAG *DAG) const { + // Emulate pop() without clobbering NodeQueueIds. + std::vector DumpQueue = Queue; + SF DumpPicker = Picker; + while (!DumpQueue.empty()) { + SUnit *SU = popFromQueue(DumpQueue, DumpPicker); + if (isBottomUp()) + dbgs() << "Height " << SU->getHeight() << ": "; + else + dbgs() << "Depth " << SU->getDepth() << ": "; + SU->dump(DAG); + } + } + protected: bool canClobber(const SUnit *SU, const SUnit *Op); void AddPseudoTwoAddrDeps(); @@ -1605,6 +1899,7 @@ if (LScratch != RScratch) return LScratch > RScratch; + // Note: with a bottom-up ready filter, the height check may be redundant. if (left->getHeight() != right->getHeight()) return left->getHeight() > right->getHeight(); @@ -1696,6 +1991,12 @@ return BURRSort(left, right, SPQ); } +// Schedule as many instructions in each cycle as possible. So don't make an +// instruction available unless it is ready in the current cycle. +bool ilp_ls_rr_sort::isReady(SUnit *SU, unsigned CurCycle) const { + return SU->getHeight() <= CurCycle; +} + bool ilp_ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const { if (left->isCall || right->isCall) @@ -2051,46 +2352,50 @@ //===----------------------------------------------------------------------===// llvm::ScheduleDAGSDNodes * -llvm::createBURRListDAGScheduler(SelectionDAGISel *IS, CodeGenOpt::Level) { +llvm::createBURRListDAGScheduler(SelectionDAGISel *IS, + CodeGenOpt::Level OptLevel) { 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); + ScheduleDAGRRList *SD = new ScheduleDAGRRList(*IS->MF, false, PQ, OptLevel); PQ->setScheduleDAG(SD); return SD; } llvm::ScheduleDAGSDNodes * -llvm::createTDRRListDAGScheduler(SelectionDAGISel *IS, CodeGenOpt::Level) { +llvm::createTDRRListDAGScheduler(SelectionDAGISel *IS, + CodeGenOpt::Level OptLevel) { 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); + ScheduleDAGRRList *SD = new ScheduleDAGRRList(*IS->MF, false, PQ, OptLevel); PQ->setScheduleDAG(SD); return SD; } llvm::ScheduleDAGSDNodes * -llvm::createSourceListDAGScheduler(SelectionDAGISel *IS, CodeGenOpt::Level) { +llvm::createSourceListDAGScheduler(SelectionDAGISel *IS, + CodeGenOpt::Level OptLevel) { 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); + ScheduleDAGRRList *SD = new ScheduleDAGRRList(*IS->MF, false, PQ, OptLevel); PQ->setScheduleDAG(SD); return SD; } llvm::ScheduleDAGSDNodes * -llvm::createHybridListDAGScheduler(SelectionDAGISel *IS, CodeGenOpt::Level) { +llvm::createHybridListDAGScheduler(SelectionDAGISel *IS, + CodeGenOpt::Level OptLevel) { const TargetMachine &TM = IS->TM; const TargetInstrInfo *TII = TM.getInstrInfo(); const TargetRegisterInfo *TRI = TM.getRegisterInfo(); @@ -2098,13 +2403,15 @@ HybridBURRPriorityQueue *PQ = new HybridBURRPriorityQueue(*IS->MF, true, TII, TRI, TLI); - ScheduleDAGRRList *SD = new ScheduleDAGRRList(*IS->MF, true, true, PQ); + + ScheduleDAGRRList *SD = new ScheduleDAGRRList(*IS->MF, true, PQ, OptLevel); PQ->setScheduleDAG(SD); return SD; } llvm::ScheduleDAGSDNodes * -llvm::createILPListDAGScheduler(SelectionDAGISel *IS, CodeGenOpt::Level) { +llvm::createILPListDAGScheduler(SelectionDAGISel *IS, + CodeGenOpt::Level OptLevel) { const TargetMachine &TM = IS->TM; const TargetInstrInfo *TII = TM.getInstrInfo(); const TargetRegisterInfo *TRI = TM.getRegisterInfo(); @@ -2112,7 +2419,7 @@ ILPBURRPriorityQueue *PQ = new ILPBURRPriorityQueue(*IS->MF, true, TII, TRI, TLI); - ScheduleDAGRRList *SD = new ScheduleDAGRRList(*IS->MF, true, true, PQ); + ScheduleDAGRRList *SD = new ScheduleDAGRRList(*IS->MF, true, PQ, OptLevel); PQ->setScheduleDAG(SD); return SD; } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=122541&r1=122540&r2=122541&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Dec 23 23:03:26 2010 @@ -1201,10 +1201,6 @@ return Ctor(this, OptLevel); } -ScheduleHazardRecognizer *SelectionDAGISel::CreateTargetHazardRecognizer() { - return new ScheduleHazardRecognizer(); -} - //===----------------------------------------------------------------------===// // Helper functions used by the generated instruction selector. //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/CodeGen/TargetInstrInfoImpl.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetInstrInfoImpl.cpp?rev=122541&r1=122540&r2=122541&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TargetInstrInfoImpl.cpp (original) +++ llvm/trunk/lib/CodeGen/TargetInstrInfoImpl.cpp Thu Dec 23 23:03:26 2010 @@ -414,8 +414,18 @@ return false; } +// Default implementation of CreateTargetPreRAHazardRecognizer. +ScheduleHazardRecognizer *TargetInstrInfoImpl:: +CreateTargetHazardRecognizer(const TargetMachine *TM, + const ScheduleDAG *DAG) const { + // Dummy hazard recognizer allows all instructions to issue. + return new ScheduleHazardRecognizer(); +} + // Default implementation of CreateTargetPostRAHazardRecognizer. ScheduleHazardRecognizer *TargetInstrInfoImpl:: -CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II) const { - return (ScheduleHazardRecognizer *)new ScoreboardHazardRecognizer(II); +CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, + const ScheduleDAG *DAG) const { + return (ScheduleHazardRecognizer *) + new ScoreboardHazardRecognizer(II, DAG, "post-RA-sched"); } Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp?rev=122541&r1=122540&r2=122541&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Thu Dec 23 23:03:26 2010 @@ -41,6 +41,13 @@ EnableARM3Addr("enable-arm-3-addr-conv", cl::Hidden, cl::desc("Enable ARM 2-addr to 3-addr conv")); +// Other targets already have a hazard recognizer enabled by default, so this +// flag currently only affects ARM. It will be generalized when it becomes a +// disabled flag. +static cl::opt EnableHazardRecognizer( + "enable-sched-hazard", cl::Hidden, + cl::desc("Enable hazard detection during preRA scheduling"), + cl::init(false)); /// ARM_MLxEntry - Record information about MLA / MLS instructions. struct ARM_MLxEntry { @@ -85,12 +92,25 @@ } } +// Use a ScoreboardHazardRecognizer for prepass ARM scheduling. TargetInstrImpl +// currently defaults to no prepass hazard recognizer. ScheduleHazardRecognizer *ARMBaseInstrInfo:: -CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II) const { +CreateTargetHazardRecognizer(const TargetMachine *TM, + const ScheduleDAG *DAG) const { + if (EnableHazardRecognizer) { + const InstrItineraryData *II = TM->getInstrItineraryData(); + return new ScoreboardHazardRecognizer(II, DAG, "pre-RA-sched"); + } + return TargetInstrInfoImpl::CreateTargetHazardRecognizer(TM, DAG); +} + +ScheduleHazardRecognizer *ARMBaseInstrInfo:: +CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, + const ScheduleDAG *DAG) const { if (Subtarget.isThumb2() || Subtarget.hasVFP2()) return (ScheduleHazardRecognizer *) - new ARMHazardRecognizer(II, *this, getRegisterInfo(), Subtarget); - return TargetInstrInfoImpl::CreateTargetPostRAHazardRecognizer(II); + new ARMHazardRecognizer(II, *this, getRegisterInfo(), Subtarget, DAG); + return TargetInstrInfoImpl::CreateTargetPostRAHazardRecognizer(II, DAG); } MachineInstr * Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h?rev=122541&r1=122540&r2=122541&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h Thu Dec 23 23:03:26 2010 @@ -211,7 +211,12 @@ const ARMSubtarget &getSubtarget() const { return Subtarget; } ScheduleHazardRecognizer * - CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II) const; + CreateTargetHazardRecognizer(const TargetMachine *TM, + const ScheduleDAG *DAG) const; + + ScheduleHazardRecognizer * + CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, + const ScheduleDAG *DAG) const; // Branch analysis. virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, Modified: llvm/trunk/lib/Target/ARM/ARMHazardRecognizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMHazardRecognizer.cpp?rev=122541&r1=122540&r2=122541&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMHazardRecognizer.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMHazardRecognizer.cpp Thu Dec 23 23:03:26 2010 @@ -34,7 +34,9 @@ } ScheduleHazardRecognizer::HazardType -ARMHazardRecognizer::getHazardType(SUnit *SU) { +ARMHazardRecognizer::getHazardType(SUnit *SU, int Stalls) { + assert(Stalls == 0 && "ARM hazards don't support scoreboard lookahead"); + MachineInstr *MI = SU->getInstr(); if (!MI->isDebugValue()) { @@ -61,19 +63,19 @@ (TII.canCauseFpMLxStall(MI->getOpcode()) || hasRAWHazard(DefMI, MI, TRI))) { // Try to schedule another instruction for the next 4 cycles. - if (Stalls == 0) - Stalls = 4; + if (FpMLxStalls == 0) + FpMLxStalls = 4; return Hazard; } } } - return ScoreboardHazardRecognizer::getHazardType(SU); + return ScoreboardHazardRecognizer::getHazardType(SU, Stalls); } void ARMHazardRecognizer::Reset() { LastMI = 0; - Stalls = 0; + FpMLxStalls = 0; ITBlockSize = 0; ScoreboardHazardRecognizer::Reset(); } @@ -100,14 +102,14 @@ if (!MI->isDebugValue()) { LastMI = MI; - Stalls = 0; + FpMLxStalls = 0; } ScoreboardHazardRecognizer::EmitInstruction(SU); } void ARMHazardRecognizer::AdvanceCycle() { - if (Stalls && --Stalls == 0) + if (FpMLxStalls && --FpMLxStalls == 0) // Stalled for 4 cycles but still can't schedule any other instructions. LastMI = 0; ScoreboardHazardRecognizer::AdvanceCycle(); Modified: llvm/trunk/lib/Target/ARM/ARMHazardRecognizer.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMHazardRecognizer.h?rev=122541&r1=122540&r2=122541&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMHazardRecognizer.h (original) +++ llvm/trunk/lib/Target/ARM/ARMHazardRecognizer.h Thu Dec 23 23:03:26 2010 @@ -29,7 +29,7 @@ const ARMSubtarget &STI; MachineInstr *LastMI; - unsigned Stalls; + unsigned FpMLxStalls; unsigned ITBlockSize; // No. of MIs in current IT block yet to be scheduled. MachineInstr *ITBlockMIs[4]; @@ -37,11 +37,12 @@ ARMHazardRecognizer(const InstrItineraryData *ItinData, const ARMBaseInstrInfo &tii, const ARMBaseRegisterInfo &tri, - const ARMSubtarget &sti) : - ScoreboardHazardRecognizer(ItinData), TII(tii), TRI(tri), STI(sti), - LastMI(0), ITBlockSize(0) {} + const ARMSubtarget &sti, + const ScheduleDAG *DAG) : + ScoreboardHazardRecognizer(ItinData, DAG, "post-RA-sched"), TII(tii), + TRI(tri), STI(sti), LastMI(0), ITBlockSize(0) {} - virtual HazardType getHazardType(SUnit *SU); + virtual HazardType getHazardType(SUnit *SU, int Stalls); virtual void Reset(); virtual void EmitInstruction(SUnit *SU); virtual void AdvanceCycle(); Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp?rev=122541&r1=122540&r2=122541&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp Thu Dec 23 23:03:26 2010 @@ -140,6 +140,9 @@ FSWithArch = FS; CPUString = ParseSubtargetFeatures(FSWithArch, CPUString); + // After parsing Itineraries, set ItinData.IssueWidth. + computeIssueWidth(); + // Thumb2 implies at least V6T2. if (ARMArchVersion >= V6T2) ThumbMode = Thumb2; @@ -224,6 +227,21 @@ return 10; } +void ARMSubtarget::computeIssueWidth() { + unsigned allStage1Units = 0; + for (const InstrItinerary *itin = InstrItins.Itineraries; + itin->FirstStage != ~0U; ++itin) { + const InstrStage *IS = InstrItins.Stages + itin->FirstStage; + allStage1Units |= IS->getUnits(); + } + InstrItins.IssueWidth = 0; + while (allStage1Units) { + ++InstrItins.IssueWidth; + // clear the lowest bit + allStage1Units ^= allStage1Units & ~(allStage1Units - 1); + } +} + bool ARMSubtarget::enablePostRAScheduler( CodeGenOpt::Level OptLevel, TargetSubtarget::AntiDepBreakMode& Mode, Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.h?rev=122541&r1=122540&r2=122541&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMSubtarget.h (original) +++ llvm/trunk/lib/Target/ARM/ARMSubtarget.h Thu Dec 23 23:03:26 2010 @@ -156,6 +156,8 @@ std::string ParseSubtargetFeatures(const std::string &FS, const std::string &CPU); + void computeIssueWidth(); + bool hasV4TOps() const { return ARMArchVersion >= V4T; } bool hasV5TOps() const { return ARMArchVersion >= V5T; } bool hasV5TEOps() const { return ARMArchVersion >= V5TE; } Modified: llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.cpp?rev=122541&r1=122540&r2=122541&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.cpp Thu Dec 23 23:03:26 2010 @@ -41,12 +41,14 @@ /// /// \return NoHazard ScheduleHazardRecognizer::HazardType -SPUHazardRecognizer::getHazardType(SUnit *SU) +SPUHazardRecognizer::getHazardType(SUnit *SU, int Stalls) { // Initial thoughts on how to do this, but this code cannot work unless the // function's prolog and epilog code are also being scheduled so that we can // accurately determine which pipeline is being scheduled. #if 0 + assert(Stalls == 0 && "SPU hazards don't yet support scoreboard lookahead"); + const SDNode *Node = SU->getNode()->getFlaggedMachineNode(); ScheduleHazardRecognizer::HazardType retval = NoHazard; bool mustBeOdd = false; Modified: llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h?rev=122541&r1=122540&r2=122541&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h (original) +++ llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h Thu Dec 23 23:03:26 2010 @@ -30,7 +30,7 @@ public: SPUHazardRecognizer(const TargetInstrInfo &TII); - virtual HazardType getHazardType(SUnit *SU); + virtual HazardType getHazardType(SUnit *SU, int Stalls); virtual void EmitInstruction(SUnit *SU); virtual void AdvanceCycle(); virtual void EmitNoop(); Modified: llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp?rev=122541&r1=122540&r2=122541&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp Thu Dec 23 23:03:26 2010 @@ -301,14 +301,6 @@ return "Cell SPU DAG->DAG Pattern Instruction Selection"; } - /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for - /// this target when scheduling the DAG. - virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer() { - const TargetInstrInfo *II = TM.getInstrInfo(); - assert(II && "No InstrInfo?"); - return new SPUHazardRecognizer(*II); - } - private: SDValue getRC( MVT ); Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp?rev=122541&r1=122540&r2=122541&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp Thu Dec 23 23:03:26 2010 @@ -16,6 +16,7 @@ #include "SPUInstrBuilder.h" #include "SPUTargetMachine.h" #include "SPUGenInstrInfo.inc" +#include "SPUHazardRecognizers.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" @@ -54,6 +55,16 @@ RI(*TM.getSubtargetImpl(), *this) { /* NOP */ } +/// CreateTargetHazardRecognizer - Return the hazard recognizer to use for +/// this target when scheduling the DAG. +ScheduleHazardRecognizer *SPUInstrInfo::CreateTargetHazardRecognizer( + const TargetMachine *TM, + const ScheduleDAG *DAG) const { + const TargetInstrInfo *TII = TM->getInstrInfo(); + assert(TII && "No InstrInfo?"); + return new SPUHazardRecognizer(*TII); +} + unsigned SPUInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const { Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h?rev=122541&r1=122540&r2=122541&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h (original) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h Thu Dec 23 23:03:26 2010 @@ -32,6 +32,10 @@ /// virtual const SPURegisterInfo &getRegisterInfo() const { return RI; } + ScheduleHazardRecognizer * + CreateTargetHazardRecognizer(const TargetMachine *TM, + const ScheduleDAG *DAG) const; + unsigned isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const; unsigned isStoreToStackSlot(const MachineInstr *MI, Modified: llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp?rev=122541&r1=122540&r2=122541&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp Thu Dec 23 23:03:26 2010 @@ -122,7 +122,9 @@ /// instructions that wouldn't terminate the dispatch group that would cause a /// pipeline flush. ScheduleHazardRecognizer::HazardType PPCHazardRecognizer970:: -getHazardType(SUnit *SU) { +getHazardType(SUnit *SU, int Stalls) { + assert(Stalls == 0 && "PPC hazards don't support scoreboard lookahead"); + const SDNode *Node = SU->getNode()->getGluedMachineNode(); bool isFirst, isSingle, isCracked, isLoad, isStore; PPCII::PPC970_Unit InstrType = Modified: llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.h?rev=122541&r1=122540&r2=122541&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.h (original) +++ llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.h Thu Dec 23 23:03:26 2010 @@ -48,7 +48,7 @@ public: PPCHazardRecognizer970(const TargetInstrInfo &TII); - virtual HazardType getHazardType(SUnit *SU); + virtual HazardType getHazardType(SUnit *SU, int Stalls); virtual void EmitInstruction(SUnit *SU); virtual void AdvanceCycle(); Modified: llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp?rev=122541&r1=122540&r2=122541&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Thu Dec 23 23:03:26 2010 @@ -16,7 +16,6 @@ #include "PPC.h" #include "PPCPredicates.h" #include "PPCTargetMachine.h" -#include "PPCHazardRecognizers.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionAnalysis.h" @@ -155,16 +154,6 @@ return "PowerPC DAG->DAG Pattern Instruction Selection"; } - /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for - /// this target when scheduling the DAG. - virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer() { - // Should use subtarget info to pick the right hazard recognizer. For - // now, always return a PPC970 recognizer. - const TargetInstrInfo *II = TM.getInstrInfo(); - assert(II && "No InstrInfo?"); - return new PPCHazardRecognizer970(*II); - } - // Include the pieces autogenerated from the target description. #include "PPCGenDAGISel.inc" Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp?rev=122541&r1=122540&r2=122541&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp Thu Dec 23 23:03:26 2010 @@ -17,6 +17,7 @@ #include "PPCPredicates.h" #include "PPCGenInstrInfo.inc" #include "PPCTargetMachine.h" +#include "PPCHazardRecognizers.h" #include "llvm/ADT/STLExtras.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineInstrBuilder.h" @@ -39,6 +40,18 @@ : TargetInstrInfoImpl(PPCInsts, array_lengthof(PPCInsts)), TM(tm), RI(*TM.getSubtargetImpl(), *this) {} +/// CreateTargetHazardRecognizer - Return the hazard recognizer to use for +/// this target when scheduling the DAG. +ScheduleHazardRecognizer *PPCInstrInfo::CreateTargetHazardRecognizer( + const TargetMachine *TM, + const ScheduleDAG *DAG) const { + // Should use subtarget info to pick the right hazard recognizer. For + // now, always return a PPC970 recognizer. + const TargetInstrInfo *TII = TM->getInstrInfo(); + assert(TII && "No InstrInfo?"); + return new PPCHazardRecognizer970(*TII); +} + unsigned PPCInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const { switch (MI->getOpcode()) { Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h?rev=122541&r1=122540&r2=122541&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h (original) +++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h Thu Dec 23 23:03:26 2010 @@ -82,6 +82,10 @@ /// virtual const PPCRegisterInfo &getRegisterInfo() const { return RI; } + ScheduleHazardRecognizer * + CreateTargetHazardRecognizer(const TargetMachine *TM, + const ScheduleDAG *DAG) const; + unsigned isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const; unsigned isStoreToStackSlot(const MachineInstr *MI, From grosbach at apple.com Thu Dec 23 23:06:32 2010 From: grosbach at apple.com (Jim Grosbach) Date: Fri, 24 Dec 2010 05:06:32 -0000 Subject: [llvm-commits] [llvm] r122542 - /llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h Message-ID: <20101224050632.5B87A2A6C12C@llvm.org> Author: grosbach Date: Thu Dec 23 23:06:32 2010 New Revision: 122542 URL: http://llvm.org/viewvc/llvm-project?rev=122542&view=rev Log: Trailing whitespace. Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h?rev=122542&r1=122541&r2=122542&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h (original) +++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h Thu Dec 23 23:06:32 2010 @@ -58,50 +58,50 @@ public: TypeSet() {} TypeSet(MVT::SimpleValueType VT, TreePattern &TP); - TypeSet(const std::vector &VTList); - + TypeSet(const std::vector &VTList); + bool isCompletelyUnknown() const { return TypeVec.empty(); } - + bool isConcrete() const { if (TypeVec.size() != 1) return false; unsigned char T = TypeVec[0]; (void)T; assert(T < MVT::LAST_VALUETYPE || T == MVT::iPTR || T == MVT::iPTRAny); return true; } - + MVT::SimpleValueType getConcrete() const { assert(isConcrete() && "Type isn't concrete yet"); return (MVT::SimpleValueType)TypeVec[0]; } - + bool isDynamicallyResolved() const { return getConcrete() == MVT::iPTR || getConcrete() == MVT::iPTRAny; } - + const SmallVectorImpl &getTypeList() const { assert(!TypeVec.empty() && "Not a type list!"); return TypeVec; } - + bool isVoid() const { return TypeVec.size() == 1 && TypeVec[0] == MVT::isVoid; } - + /// hasIntegerTypes - Return true if this TypeSet contains any integer value /// types. bool hasIntegerTypes() const; - + /// hasFloatingPointTypes - Return true if this TypeSet contains an fAny or /// a floating point value type. bool hasFloatingPointTypes() const; - + /// hasVectorTypes - Return true if this TypeSet contains a vector value /// type. bool hasVectorTypes() const; - + /// getName() - Return this TypeSet as a string. std::string getName() const; - + /// MergeInTypeInfo - This merges in type information from the specified /// argument. If 'this' changes, it returns true. If the two types are /// contradictory (e.g. merge f32 into i32) then this throws an exception. @@ -126,14 +126,14 @@ /// EnforceSmallerThan - 'this' must be a smaller VT than Other. Update /// this an other based on this information. bool EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP); - + /// EnforceVectorEltTypeIs - 'this' is now constrainted to be a vector type /// whose element is VT. bool EnforceVectorEltTypeIs(EEVT::TypeSet &VT, TreePattern &TP); - + bool operator!=(const TypeSet &RHS) const { return TypeVec != RHS.TypeVec; } bool operator==(const TypeSet &RHS) const { return TypeVec == RHS.TypeVec; } - + private: /// FillWithPossibleTypes - Set to all legal types and return true, only /// valid on completely unknown type sets. If Pred is non-null, only MVTs @@ -151,13 +151,13 @@ /// corresponding to the SDTypeConstraint tablegen class in Target.td. struct SDTypeConstraint { SDTypeConstraint(Record *R); - + unsigned OperandNo; // The operand # this constraint applies to. - enum { - SDTCisVT, SDTCisPtrTy, SDTCisInt, SDTCisFP, SDTCisVec, SDTCisSameAs, + enum { + SDTCisVT, SDTCisPtrTy, SDTCisInt, SDTCisFP, SDTCisVec, SDTCisSameAs, SDTCisVTSmallerThanOp, SDTCisOpSmallerThanOp, SDTCisEltOfVec } ConstraintType; - + union { // The discriminated union. struct { MVT::SimpleValueType VT; @@ -197,25 +197,25 @@ std::vector TypeConstraints; public: SDNodeInfo(Record *R); // Parse the specified record. - + unsigned getNumResults() const { return NumResults; } - + /// getNumOperands - This is the number of operands required or -1 if /// variadic. int getNumOperands() const { return NumOperands; } Record *getRecord() const { return Def; } const std::string &getEnumName() const { return EnumName; } const std::string &getSDClassName() const { return SDClassName; } - + const std::vector &getTypeConstraints() const { return TypeConstraints; } - + /// getKnownType - If the type constraints on this node imply a fixed type /// (e.g. all stores return void, etc), then return it as an /// MVT::SimpleValueType. Otherwise, return MVT::Other. MVT::SimpleValueType getKnownType(unsigned ResNo) const; - + /// hasProperty - Return true if this node has the specified property. /// bool hasProperty(enum SDNP Prop) const { return Properties & (1 << Prop); } @@ -240,31 +240,31 @@ /// result may be a set of possible types. After (successful) type inference, /// each is a single concrete type. SmallVector Types; - + /// Operator - The Record for the operator if this is an interior node (not /// a leaf). Record *Operator; - + /// Val - The init value (e.g. the "GPRC" record, or "7") for a leaf. /// Init *Val; - + /// Name - The name given to this node with the :$foo notation. /// std::string Name; - + /// PredicateFns - The predicate functions to execute on this node to check /// for a match. If this list is empty, no predicate is involved. std::vector PredicateFns; - + /// TransformFn - The transformation function to execute on this node before /// it can be substituted into the resulting instruction on a pattern match. Record *TransformFn; - + std::vector Children; public: TreePatternNode(Record *Op, const std::vector &Ch, - unsigned NumResults) + unsigned NumResults) : Operator(Op), Val(0), TransformFn(0), Children(Ch) { Types.resize(NumResults); } @@ -273,12 +273,12 @@ Types.resize(NumResults); } ~TreePatternNode(); - + const std::string &getName() const { return Name; } void setName(StringRef N) { Name.assign(N.begin(), N.end()); } - + bool isLeaf() const { return Val != 0; } - + // Type accessors. unsigned getNumTypes() const { return Types.size(); } MVT::SimpleValueType getType(unsigned ResNo) const { @@ -288,7 +288,7 @@ const EEVT::TypeSet &getExtType(unsigned ResNo) const { return Types[ResNo]; } EEVT::TypeSet &getExtType(unsigned ResNo) { return Types[ResNo]; } void setType(unsigned ResNo, const EEVT::TypeSet &T) { Types[ResNo] = T; } - + bool hasTypeSet(unsigned ResNo) const { return Types[ResNo].isConcrete(); } @@ -298,16 +298,16 @@ bool isTypeDynamicallyResolved(unsigned ResNo) const { return Types[ResNo].isDynamicallyResolved(); } - + Init *getLeafValue() const { assert(isLeaf()); return Val; } Record *getOperator() const { assert(!isLeaf()); return Operator; } - + unsigned getNumChildren() const { return Children.size(); } TreePatternNode *getChild(unsigned N) const { return Children[N]; } void setChild(unsigned i, TreePatternNode *N) { Children[i] = N; } - + /// hasChild - Return true if N is any of our children. bool hasChild(const TreePatternNode *N) const { for (unsigned i = 0, e = Children.size(); i != e; ++i) @@ -321,7 +321,7 @@ assert(PredicateFns.empty() && "Overwriting non-empty predicate list!"); PredicateFns = Fns; } - void addPredicateFn(const std::string &Fn) { + void addPredicateFn(const std::string &Fn) { assert(!Fn.empty() && "Empty predicate string!"); if (std::find(PredicateFns.begin(), PredicateFns.end(), Fn) == PredicateFns.end()) @@ -330,7 +330,7 @@ Record *getTransformFn() const { return TransformFn; } void setTransformFn(Record *Fn) { TransformFn = Fn; } - + /// getIntrinsicInfo - If this node corresponds to an intrinsic, return the /// CodeGenIntrinsic information for it, otherwise return a null pointer. const CodeGenIntrinsic *getIntrinsicInfo(const CodeGenDAGPatterns &CDP) const; @@ -342,18 +342,18 @@ /// NodeHasProperty - Return true if this node has the specified property. bool NodeHasProperty(SDNP Property, const CodeGenDAGPatterns &CGP) const; - + /// TreeHasProperty - Return true if any node in this tree has the specified /// property. bool TreeHasProperty(SDNP Property, const CodeGenDAGPatterns &CGP) const; - + /// isCommutativeIntrinsic - Return true if the node is an intrinsic which is /// marked isCommutative. bool isCommutativeIntrinsic(const CodeGenDAGPatterns &CDP) const; - + void print(raw_ostream &OS) const; void dump() const; - + public: // Higher level manipulation routines. /// clone - Return a new copy of this tree. @@ -362,14 +362,14 @@ /// RemoveAllTypes - Recursively strip all the types of this tree. void RemoveAllTypes(); - + /// isIsomorphicTo - Return true if this node is recursively isomorphic to /// the specified node. For this comparison, all of the state of the node /// is considered, except for the assigned name. Nodes with differing names /// that are otherwise identical are considered isomorphic. bool isIsomorphicTo(const TreePatternNode *N, const MultipleUseVarSet &DepVars) const; - + /// SubstituteFormalArguments - Replace the formal arguments in this tree /// with actual values specified by ArgMap. void SubstituteFormalArguments(std::mapContainsUnresolvedType()) return true; return false; } - + /// canPatternMatch - If it is impossible for this pattern to match on this /// target, fill in Reason and return false. Otherwise, return true. bool canPatternMatch(std::string &Reason, const CodeGenDAGPatterns &CDP); @@ -420,7 +420,7 @@ TPN.print(OS); return OS; } - + /// TreePattern - Represent a pattern, used for instructions, pattern /// fragments, etc. @@ -430,19 +430,19 @@ /// Note that PatFrag's only have a single tree. /// std::vector Trees; - + /// NamedNodes - This is all of the nodes that have names in the trees in this /// pattern. StringMap > NamedNodes; - + /// TheRecord - The actual TableGen record corresponding to this pattern. /// Record *TheRecord; - + /// Args - This is a list of all of the arguments to this pattern (for /// PatFrag patterns), which are the 'node' markers in this pattern. std::vector Args; - + /// CDP - the top-level object coordinating this madness. /// CodeGenDAGPatterns &CDP; @@ -451,7 +451,7 @@ /// False if this is an output pattern, something to emit. bool isInputPattern; public: - + /// TreePattern constructor - Parse the specified DagInits into the /// current record. TreePattern(Record *TheRec, ListInit *RawPat, bool isInput, @@ -460,7 +460,7 @@ CodeGenDAGPatterns &ise); TreePattern(Record *TheRec, TreePatternNode *Pat, bool isInput, CodeGenDAGPatterns &ise); - + /// getTrees - Return the tree patterns which corresponds to this pattern. /// const std::vector &getTrees() const { return Trees; } @@ -470,25 +470,25 @@ assert(Trees.size() == 1 && "Doesn't have exactly one pattern!"); return Trees[0]; } - + const StringMap > &getNamedNodesMap() { if (NamedNodes.empty()) ComputeNamedNodes(); return NamedNodes; } - + /// getRecord - Return the actual TableGen record corresponding to this /// pattern. /// Record *getRecord() const { return TheRecord; } - + unsigned getNumArgs() const { return Args.size(); } const std::string &getArgName(unsigned i) const { assert(i < Args.size() && "Argument reference out of range!"); return Args[i]; } std::vector &getArgList() { return Args; } - + CodeGenDAGPatterns &getDAGPatterns() const { return CDP; } /// InlinePatternFragments - If this pattern refers to any pattern @@ -498,20 +498,20 @@ for (unsigned i = 0, e = Trees.size(); i != e; ++i) Trees[i] = Trees[i]->InlinePatternFragments(*this); } - + /// InferAllTypes - Infer/propagate as many types throughout the expression /// patterns as possible. Return true if all types are inferred, false /// otherwise. Throw an exception if a type contradiction is found. bool InferAllTypes(const StringMap > *NamedTypes=0); - + /// error - Throw an exception, prefixing it with information about this /// pattern. void error(const std::string &Msg) const; - + void print(raw_ostream &OS) const; void dump() const; - + private: TreePatternNode *ParseTreePattern(Init *DI, StringRef OpName); void ComputeNamedNodes(); @@ -535,7 +535,7 @@ const std::vector &results, const std::vector &operands, const std::vector &impresults) - : Pattern(TP), Results(results), Operands(operands), + : Pattern(TP), Results(results), Operands(operands), ImpResults(impresults), ResultPattern(0) {} const TreePattern *getPattern() const { return Pattern; } @@ -543,14 +543,14 @@ unsigned getNumOperands() const { return Operands.size(); } unsigned getNumImpResults() const { return ImpResults.size(); } const std::vector& getImpResults() const { return ImpResults; } - + void setResultPattern(TreePatternNode *R) { ResultPattern = R; } - + Record *getResult(unsigned RN) const { assert(RN < Results.size()); return Results[RN]; } - + Record *getOperand(unsigned ON) const { assert(ON < Operands.size()); return Operands[ON]; @@ -560,10 +560,10 @@ assert(RN < ImpResults.size()); return ImpResults[RN]; } - + TreePatternNode *getResultPattern() const { return ResultPattern; } }; - + /// PatternToMatch - Used by CodeGenDAGPatterns to keep tab of patterns /// processed to produce isel. class PatternToMatch { @@ -591,7 +591,7 @@ unsigned getAddedComplexity() const { return AddedComplexity; } std::string getPredicateCheck() const; - + /// Compute the complexity metric for the input pattern. This roughly /// corresponds to the number of nodes that are covered. unsigned getPatternComplexity(const CodeGenDAGPatterns &CGP) const; @@ -601,60 +601,60 @@ struct RecordPtrCmp { bool operator()(const Record *LHS, const Record *RHS) const; }; - + class CodeGenDAGPatterns { RecordKeeper &Records; CodeGenTarget Target; std::vector Intrinsics; std::vector TgtIntrinsics; - + std::map SDNodes; std::map, RecordPtrCmp> SDNodeXForms; std::map ComplexPatterns; std::map PatternFragments; std::map DefaultOperands; std::map Instructions; - + // Specific SDNode definitions: Record *intrinsic_void_sdnode; Record *intrinsic_w_chain_sdnode, *intrinsic_wo_chain_sdnode; - + /// PatternsToMatch - All of the things we are matching on the DAG. The first /// value is the pattern to match, the second pattern is the result to /// emit. std::vector PatternsToMatch; public: - CodeGenDAGPatterns(RecordKeeper &R); + CodeGenDAGPatterns(RecordKeeper &R); ~CodeGenDAGPatterns(); - + CodeGenTarget &getTargetInfo() { return Target; } const CodeGenTarget &getTargetInfo() const { return Target; } - + Record *getSDNodeNamed(const std::string &Name) const; - + const SDNodeInfo &getSDNodeInfo(Record *R) const { assert(SDNodes.count(R) && "Unknown node!"); return SDNodes.find(R)->second; } - + // Node transformation lookups. typedef std::pair NodeXForm; const NodeXForm &getSDNodeTransform(Record *R) const { assert(SDNodeXForms.count(R) && "Invalid transform!"); return SDNodeXForms.find(R)->second; } - + typedef std::map::const_iterator nx_iterator; nx_iterator nx_begin() const { return SDNodeXForms.begin(); } nx_iterator nx_end() const { return SDNodeXForms.end(); } - + const ComplexPattern &getComplexPattern(Record *R) const { assert(ComplexPatterns.count(R) && "Unknown addressing mode!"); return ComplexPatterns.find(R)->second; } - + const CodeGenIntrinsic &getIntrinsic(Record *R) const { for (unsigned i = 0, e = Intrinsics.size(); i != e; ++i) if (Intrinsics[i].TheDef == R) return Intrinsics[i]; @@ -663,7 +663,7 @@ assert(0 && "Unknown intrinsic!"); abort(); } - + const CodeGenIntrinsic &getIntrinsicInfo(unsigned IID) const { if (IID-1 < Intrinsics.size()) return Intrinsics[IID-1]; @@ -672,7 +672,7 @@ assert(0 && "Bad intrinsic ID!"); abort(); } - + unsigned getIntrinsicID(Record *R) const { for (unsigned i = 0, e = Intrinsics.size(); i != e; ++i) if (Intrinsics[i].TheDef == R) return i; @@ -681,12 +681,12 @@ assert(0 && "Unknown intrinsic!"); abort(); } - + const DAGDefaultOperand &getDefaultOperand(Record *R) const { assert(DefaultOperands.count(R) &&"Isn't an analyzed default operand!"); return DefaultOperands.find(R)->second; } - + // Pattern Fragment information. TreePattern *getPatternFragment(Record *R) const { assert(PatternFragments.count(R) && "Invalid pattern fragment request!"); @@ -696,7 +696,7 @@ if (!PatternFragments.count(R)) return 0; return PatternFragments.find(R)->second; } - + typedef std::map::const_iterator pf_iterator; pf_iterator pf_begin() const { return PatternFragments.begin(); } @@ -706,14 +706,14 @@ typedef std::vector::const_iterator ptm_iterator; ptm_iterator ptm_begin() const { return PatternsToMatch.begin(); } ptm_iterator ptm_end() const { return PatternsToMatch.end(); } - - - + + + const DAGInstruction &getInstruction(Record *R) const { assert(Instructions.count(R) && "Unknown instruction!"); return Instructions.find(R)->second; } - + Record *get_intrinsic_void_sdnode() const { return intrinsic_void_sdnode; } @@ -723,7 +723,7 @@ Record *get_intrinsic_wo_chain_sdnode() const { return intrinsic_wo_chain_sdnode; } - + bool hasTargetIntrinsics() { return !TgtIntrinsics.empty(); } private: @@ -736,7 +736,7 @@ void ParsePatterns(); void InferInstructionFlags(); void GenerateVariants(); - + void AddPatternToMatch(const TreePattern *Pattern, const PatternToMatch &PTM); void FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat, std::map References: <20101224050326.B00E12A6C12C@llvm.org> Message-ID: <86A29E65-11AB-4D3F-BDDB-5F877D579128@apple.com> Looks great! Evan On Dec 23, 2010, at 9:03 PM, Andrew Trick wrote: > Author: atrick > Date: Thu Dec 23 23:03:26 2010 > New Revision: 122541 > > URL: http://llvm.org/viewvc/llvm-project?rev=122541&view=rev > Log: > Various bits of framework needed for precise machine-level selection > DAG scheduling during isel. Most new functionality is currently > guarded by -enable-sched-cycles and -enable-sched-hazard. > > Added InstrItineraryData::IssueWidth field, currently derived from > ARM itineraries, but could be initialized differently on other targets. > > Added ScheduleHazardRecognizer::MaxLookAhead to indicate whether it is > active, and if so how many cycles of state it holds. > > Added SchedulingPriorityQueue::HasReadyFilter to allowing gating entry > into the scheduler's available queue. > > ScoreboardHazardRecognizer now accesses the ScheduleDAG in order to > get information about it's SUnits, provides RecedeCycle for bottom-up > scheduling, correctly computes scoreboard depth, tracks IssueCount, and > considers potential stall cycles when checking for hazards. > > ScheduleDAGRRList now models machine cycles and hazards (under > flags). It tracks MinAvailableCycle, drives the hazard recognizer and > priority queue's ready filter, manages a new PendingQueue, properly > accounts for stall cycles, etc. > > Modified: > llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h > llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h > llvm/trunk/include/llvm/CodeGen/ScheduleHazardRecognizer.h > llvm/trunk/include/llvm/CodeGen/ScoreboardHazardRecognizer.h > llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h > llvm/trunk/include/llvm/Target/TargetInstrInfo.h > llvm/trunk/include/llvm/Target/TargetInstrItineraries.h > llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp > llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp > llvm/trunk/lib/CodeGen/ScheduleDAG.cpp > llvm/trunk/lib/CodeGen/ScoreboardHazardRecognizer.cpp > llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp > llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp > llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp > llvm/trunk/lib/CodeGen/TargetInstrInfoImpl.cpp > llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp > llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h > llvm/trunk/lib/Target/ARM/ARMHazardRecognizer.cpp > llvm/trunk/lib/Target/ARM/ARMHazardRecognizer.h > llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp > llvm/trunk/lib/Target/ARM/ARMSubtarget.h > llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.cpp > llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h > llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp > llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp > llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h > llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp > llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.h > llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp > llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp > llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h > > Modified: llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h (original) > +++ llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h Thu Dec 23 23:03:26 2010 > @@ -47,6 +47,8 @@ > LatencyPriorityQueue() : Picker(this) { > } > > + bool isBottomUp() const { return false; } > + > void initNodes(std::vector &sunits) { > SUnits = &sunits; > NumNodesSolelyBlocking.resize(SUnits->size(), 0); > @@ -81,6 +83,8 @@ > > virtual void remove(SUnit *SU); > > + virtual void dump(ScheduleDAG* DAG) const; > + > // ScheduledNode - As nodes are scheduled, we look to see if there are any > // successor nodes that have a single unscheduled predecessor. If so, that > // single predecessor has a higher priority, since scheduling it will make > > Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) > +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Thu Dec 23 23:03:26 2010 > @@ -326,6 +326,10 @@ > return Node; > } > > + /// isInstr - Return true if this SUnit refers to a machine instruction as > + /// opposed to an SDNode. > + bool isInstr() const { return !Node; } > + > /// setInstr - Assign the instruction for the SUnit. > /// This may be used during post-regalloc scheduling. > void setInstr(MachineInstr *MI) { > @@ -421,16 +425,27 @@ > /// > class SchedulingPriorityQueue { > unsigned CurCycle; > + bool HasReadyFilter; > public: > - SchedulingPriorityQueue() : CurCycle(0) {} > + SchedulingPriorityQueue(bool rf = false): > + CurCycle(0), HasReadyFilter(rf) {} > virtual ~SchedulingPriorityQueue() {} > > + virtual bool isBottomUp() const = 0; > + > virtual void initNodes(std::vector &SUnits) = 0; > virtual void addNode(const SUnit *SU) = 0; > virtual void updateNode(const SUnit *SU) = 0; > virtual void releaseState() = 0; > > virtual bool empty() const = 0; > + > + bool hasReadyFilter() const { return HasReadyFilter; } > + > + virtual bool isReady(SUnit *U) const { > + assert(!HasReadyFilter && "The ready filter must override isReady()"); > + return true; > + } > virtual void push(SUnit *U) = 0; > > void push_all(const std::vector &Nodes) { > @@ -443,6 +458,8 @@ > > virtual void remove(SUnit *SU) = 0; > > + virtual void dump(ScheduleDAG *DAG) const {} > + > /// ScheduledNode - As each node is scheduled, this method is invoked. This > /// allows the priority function to adjust the priority of related > /// unscheduled nodes, for example. > @@ -479,6 +496,13 @@ > > virtual ~ScheduleDAG(); > > + /// getInstrDesc - Return the TargetInstrDesc of this SUnit. > + /// Return NULL for SDNodes without a machine opcode. > + const TargetInstrDesc *getInstrDesc(const SUnit *SU) const { > + if (SU->isInstr()) return &SU->getInstr()->getDesc(); > + return getNodeDesc(SU->getNode()); > + } > + > /// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered > /// using 'dot'. > /// > @@ -542,6 +566,10 @@ > void EmitNoop(); > > void EmitPhysRegCopy(SUnit *SU, DenseMap &VRBaseMap); > + > + private: > + // Return the TargetInstrDesc of this SDNode or NULL. > + const TargetInstrDesc *getNodeDesc(const SDNode *Node) const; > }; > > class SUnitIterator : public std::iterator > Modified: llvm/trunk/include/llvm/CodeGen/ScheduleHazardRecognizer.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleHazardRecognizer.h?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/CodeGen/ScheduleHazardRecognizer.h (original) > +++ llvm/trunk/include/llvm/CodeGen/ScheduleHazardRecognizer.h Thu Dec 23 23:03:26 2010 > @@ -23,7 +23,15 @@ > /// issued this cycle, and whether or not a noop needs to be inserted to handle > /// the hazard. > class ScheduleHazardRecognizer { > +protected: > + /// MaxLookAhead - Indicate the number of cycles in the scoreboard > + /// state. Important to restore the state after backtracking. Additionally, > + /// MaxLookAhead=0 identifies a fake recognizer, allowing the client to > + /// bypass virtual calls. Currently the PostRA scheduler ignores it. > + unsigned MaxLookAhead; > + > public: > + ScheduleHazardRecognizer(): MaxLookAhead(0) {} > virtual ~ScheduleHazardRecognizer(); > > enum HazardType { > @@ -32,6 +40,12 @@ > NoopHazard // This instruction can't be emitted, and needs noops. > }; > > + unsigned getMaxLookAhead() const { return MaxLookAhead; } > + > + /// atIssueLimit - Return true if no more instructions may be issued in this > + /// cycle. > + virtual bool atIssueLimit() const { return false; } > + > /// getHazardType - Return the hazard type of emitting this node. There are > /// three possible results. Either: > /// * NoHazard: it is legal to issue this instruction on this cycle. > @@ -39,7 +53,7 @@ > /// other instruction is available, issue it first. > /// * NoopHazard: issuing this instruction would break the program. If > /// some other instruction can be issued, do so, otherwise issue a noop. > - virtual HazardType getHazardType(SUnit *) { > + virtual HazardType getHazardType(SUnit *m, int Stalls) { > return NoHazard; > } > > @@ -52,12 +66,18 @@ > /// emitted, to advance the hazard state. > virtual void EmitInstruction(SUnit *) {} > > - /// AdvanceCycle - This callback is invoked when no instructions can be > - /// issued on this cycle without a hazard. This should increment the > + /// AdvanceCycle - This callback is invoked whenever the next top-down > + /// instruction to be scheduled cannot issue in the current cycle, either > + /// because of latency or resource conflicts. This should increment the > /// internal state of the hazard recognizer so that previously "Hazard" > /// instructions will now not be hazards. > virtual void AdvanceCycle() {} > > + /// RecedeCycle - This callback is invoked whenever the next bottom-up > + /// instruction to be scheduled cannot issue in the current cycle, either > + /// because of latency or resource conflicts. > + virtual void RecedeCycle() {} > + > /// EmitNoop - This callback is invoked when a noop was added to the > /// instruction stream. > virtual void EmitNoop() { > > Modified: llvm/trunk/include/llvm/CodeGen/ScoreboardHazardRecognizer.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScoreboardHazardRecognizer.h?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/CodeGen/ScoreboardHazardRecognizer.h (original) > +++ llvm/trunk/include/llvm/CodeGen/ScoreboardHazardRecognizer.h Thu Dec 23 23:03:26 2010 > @@ -26,6 +26,8 @@ > namespace llvm { > > class InstrItineraryData; > +class TargetInstrDesc; > +class ScheduleDAG; > class SUnit; > > class ScoreboardHazardRecognizer : public ScheduleHazardRecognizer { > @@ -84,16 +86,38 @@ > void dump() const; > }; > > +#ifndef NDEBUG > + // Support for tracing ScoreboardHazardRecognizer as a component within > + // another module. Follows the current thread-unsafe model of tracing. > + static const char *DebugType; > +#endif > + > // Itinerary data for the target. > const InstrItineraryData *ItinData; > > + const ScheduleDAG *DAG; > + > + /// IssueWidth - Max issue per cycle. 0=Unknown. > + unsigned IssueWidth; > + > + /// IssueCount - Count instructions issued in this cycle. > + unsigned IssueCount; > + > Scoreboard ReservedScoreboard; > Scoreboard RequiredScoreboard; > > public: > - ScoreboardHazardRecognizer(const InstrItineraryData *ItinData); > - > - virtual HazardType getHazardType(SUnit *SU); > + ScoreboardHazardRecognizer(const InstrItineraryData *ItinData, > + const ScheduleDAG *DAG, > + const char *ParentDebugType = ""); > + > + /// atIssueLimit - Return true if no more instructions may be issued in this > + /// cycle. > + virtual bool atIssueLimit() const; > + > + // Stalls provides an cycle offset at which SU will be scheduled. It will be > + // negative for bottom-up scheduling. > + virtual HazardType getHazardType(SUnit *SU, int Stalls); > virtual void Reset(); > virtual void EmitInstruction(SUnit *SU); > virtual void AdvanceCycle(); > > Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h (original) > +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h Thu Dec 23 23:03:26 2010 > @@ -98,11 +98,6 @@ > CodeGenOpt::Level OptLevel, > bool IgnoreChains = false); > > - /// CreateTargetHazardRecognizer - Return a newly allocated hazard recognizer > - /// to use for this target when scheduling the DAG. > - virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer(); > - > - > // Opcodes used by the DAG state machine: > enum BuiltinOpcodes { > OPC_Scope, > > Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrInfo.h?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Target/TargetInstrInfo.h (original) > +++ llvm/trunk/include/llvm/Target/TargetInstrInfo.h Thu Dec 23 23:03:26 2010 > @@ -29,6 +29,7 @@ > class SDNode; > class ScheduleHazardRecognizer; > class SelectionDAG; > +class ScheduleDAG; > class TargetRegisterClass; > class TargetRegisterInfo; > > @@ -563,11 +564,19 @@ > virtual unsigned getInlineAsmLength(const char *Str, > const MCAsmInfo &MAI) const; > > - /// CreateTargetHazardRecognizer - Allocate and return a hazard recognizer > - /// to use for this target when scheduling the machine instructions after > - /// register allocation. > + /// CreateTargetPreRAHazardRecognizer - Allocate and return a hazard > + /// recognizer to use for this target when scheduling the machine instructions > + /// before register allocation. > virtual ScheduleHazardRecognizer* > - CreateTargetPostRAHazardRecognizer(const InstrItineraryData*) const = 0; > + CreateTargetHazardRecognizer(const TargetMachine *TM, > + const ScheduleDAG *DAG) const = 0; > + > + /// CreateTargetPostRAHazardRecognizer - Allocate and return a hazard > + /// recognizer to use for this target when scheduling the machine instructions > + /// after register allocation. > + virtual ScheduleHazardRecognizer* > + CreateTargetPostRAHazardRecognizer(const InstrItineraryData*, > + const ScheduleDAG *DAG) const = 0; > > /// AnalyzeCompare - For a comparison instruction, return the source register > /// in SrcReg and the value it compares against in CmpValue. Return true if > @@ -674,7 +683,11 @@ > const MachineFunction &MF) const; > > virtual ScheduleHazardRecognizer * > - CreateTargetPostRAHazardRecognizer(const InstrItineraryData*) const; > + CreateTargetHazardRecognizer(const TargetMachine*, const ScheduleDAG*) const; > + > + virtual ScheduleHazardRecognizer * > + CreateTargetPostRAHazardRecognizer(const InstrItineraryData*, > + const ScheduleDAG*) const; > }; > > } // End llvm namespace > > Modified: llvm/trunk/include/llvm/Target/TargetInstrItineraries.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrItineraries.h?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Target/TargetInstrItineraries.h (original) > +++ llvm/trunk/include/llvm/Target/TargetInstrItineraries.h Thu Dec 23 23:03:26 2010 > @@ -113,11 +113,13 @@ > const unsigned *OperandCycles; ///< Array of operand cycles selected > const unsigned *Forwardings; ///< Array of pipeline forwarding pathes > const InstrItinerary *Itineraries; ///< Array of itineraries selected > + unsigned IssueWidth; ///< Max issue per cycle. 0=Unknown. > > /// Ctors. > /// > InstrItineraryData() : Stages(0), OperandCycles(0), Forwardings(0), > - Itineraries(0) {} > + Itineraries(0), IssueWidth(0) {} > + > InstrItineraryData(const InstrStage *S, const unsigned *OS, > const unsigned *F, const InstrItinerary *I) > : Stages(S), OperandCycles(OS), Forwardings(F), Itineraries(I) {} > > Modified: llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp (original) > +++ llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp Thu Dec 23 23:03:26 2010 > @@ -16,6 +16,7 @@ > #define DEBUG_TYPE "scheduler" > #include "llvm/CodeGen/LatencyPriorityQueue.h" > #include "llvm/Support/Debug.h" > +#include "llvm/Support/raw_ostream.h" > using namespace llvm; > > bool latency_sort::operator()(const SUnit *LHS, const SUnit *RHS) const { > @@ -136,3 +137,16 @@ > std::swap(*I, Queue.back()); > Queue.pop_back(); > } > + > +#ifdef NDEBUG > +void LatencyPriorityQueue::dump(ScheduleDAG *DAG) const {} > +#else > +void LatencyPriorityQueue::dump(ScheduleDAG *DAG) const { > + LatencyPriorityQueue q = *this; > + while (!q.empty()) { > + SUnit *su = q.pop(); > + dbgs() << "Height " << su->getHeight() << ": "; > + su->dump(DAG); > + } > +} > +#endif > > Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) > +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Thu Dec 23 23:03:26 2010 > @@ -133,18 +133,12 @@ > std::vector KillIndices; > > public: > - SchedulePostRATDList(MachineFunction &MF, > - const MachineLoopInfo &MLI, > - const MachineDominatorTree &MDT, > - ScheduleHazardRecognizer *HR, > - AntiDepBreaker *ADB, > - AliasAnalysis *aa) > - : ScheduleDAGInstrs(MF, MLI, MDT), Topo(SUnits), > - HazardRec(HR), AntiDepBreak(ADB), AA(aa), > - KillIndices(TRI->getNumRegs()) {} > + SchedulePostRATDList( > + MachineFunction &MF, MachineLoopInfo &MLI, MachineDominatorTree &MDT, > + AliasAnalysis *AA, TargetSubtarget::AntiDepBreakMode AntiDepMode, > + SmallVectorImpl &CriticalPathRCs); > > - ~SchedulePostRATDList() { > - } > + ~SchedulePostRATDList(); > > /// StartBlock - Initialize register live-range state for scheduling in > /// this block. > @@ -183,9 +177,34 @@ > }; > } > > +SchedulePostRATDList::SchedulePostRATDList( > + MachineFunction &MF, MachineLoopInfo &MLI, MachineDominatorTree &MDT, > + AliasAnalysis *AA, TargetSubtarget::AntiDepBreakMode AntiDepMode, > + SmallVectorImpl &CriticalPathRCs) > + : ScheduleDAGInstrs(MF, MLI, MDT), Topo(SUnits), AA(AA), > + KillIndices(TRI->getNumRegs()) > +{ > + const TargetMachine &TM = MF.getTarget(); > + const InstrItineraryData *InstrItins = TM.getInstrItineraryData(); > + HazardRec = > + TM.getInstrInfo()->CreateTargetPostRAHazardRecognizer(InstrItins, this); > + AntiDepBreak = > + ((AntiDepMode == TargetSubtarget::ANTIDEP_ALL) ? > + (AntiDepBreaker *)new AggressiveAntiDepBreaker(MF, CriticalPathRCs) : > + ((AntiDepMode == TargetSubtarget::ANTIDEP_CRITICAL) ? > + (AntiDepBreaker *)new CriticalAntiDepBreaker(MF) : NULL)); > +} > + > +SchedulePostRATDList::~SchedulePostRATDList() { > + delete HazardRec; > + delete AntiDepBreak; > +} > + > bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) { > - AA = &getAnalysis(); > TII = Fn.getTarget().getInstrInfo(); > + MachineLoopInfo &MLI = getAnalysis(); > + MachineDominatorTree &MDT = getAnalysis(); > + AliasAnalysis *AA = &getAnalysis(); > > // Check for explicit enable/disable of post-ra scheduling. > TargetSubtarget::AntiDepBreakMode AntiDepMode = TargetSubtarget::ANTIDEP_NONE; > @@ -195,6 +214,7 @@ > return false; > } else { > // Check that post-RA scheduling is enabled for this target. > + // This may upgrade the AntiDepMode. > const TargetSubtarget &ST = Fn.getTarget().getSubtarget(); > if (!ST.enablePostRAScheduler(OptLevel, AntiDepMode, CriticalPathRCs)) > return false; > @@ -210,19 +230,8 @@ > > DEBUG(dbgs() << "PostRAScheduler\n"); > > - const MachineLoopInfo &MLI = getAnalysis(); > - const MachineDominatorTree &MDT = getAnalysis(); > - const TargetMachine &TM = Fn.getTarget(); > - const InstrItineraryData *InstrItins = TM.getInstrItineraryData(); > - ScheduleHazardRecognizer *HR = > - TM.getInstrInfo()->CreateTargetPostRAHazardRecognizer(InstrItins); > - AntiDepBreaker *ADB = > - ((AntiDepMode == TargetSubtarget::ANTIDEP_ALL) ? > - (AntiDepBreaker *)new AggressiveAntiDepBreaker(Fn, CriticalPathRCs) : > - ((AntiDepMode == TargetSubtarget::ANTIDEP_CRITICAL) ? > - (AntiDepBreaker *)new CriticalAntiDepBreaker(Fn) : NULL)); > - > - SchedulePostRATDList Scheduler(Fn, MLI, MDT, HR, ADB, AA); > + SchedulePostRATDList Scheduler(Fn, MLI, MDT, AA, AntiDepMode, > + CriticalPathRCs); > > // Loop over all of the basic blocks > for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); > @@ -270,9 +279,6 @@ > Scheduler.FixupKills(MBB); > } > > - delete HR; > - delete ADB; > - > return true; > } > > @@ -617,13 +623,7 @@ > MinDepth = PendingQueue[i]->getDepth(); > } > > - DEBUG(dbgs() << "\n*** Examining Available\n"; > - LatencyPriorityQueue q = AvailableQueue; > - while (!q.empty()) { > - SUnit *su = q.pop(); > - dbgs() << "Height " << su->getHeight() << ": "; > - su->dump(this); > - }); > + DEBUG(dbgs() << "\n*** Examining Available\n"; AvailableQueue.dump(this)); > > SUnit *FoundSUnit = 0; > bool HasNoopHazards = false; > @@ -631,7 +631,7 @@ > SUnit *CurSUnit = AvailableQueue.pop(); > > ScheduleHazardRecognizer::HazardType HT = > - HazardRec->getHazardType(CurSUnit); > + HazardRec->getHazardType(CurSUnit, 0/*no stalls*/); > if (HT == ScheduleHazardRecognizer::NoHazard) { > FoundSUnit = CurSUnit; > break; > > Modified: llvm/trunk/lib/CodeGen/ScheduleDAG.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAG.cpp?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/lib/CodeGen/ScheduleDAG.cpp (original) > +++ llvm/trunk/lib/CodeGen/ScheduleDAG.cpp Thu Dec 23 23:03:26 2010 > @@ -15,6 +15,7 @@ > #define DEBUG_TYPE "pre-RA-sched" > #include "llvm/CodeGen/ScheduleDAG.h" > #include "llvm/CodeGen/ScheduleHazardRecognizer.h" > +#include "llvm/CodeGen/SelectionDAGNodes.h" > #include "llvm/Target/TargetMachine.h" > #include "llvm/Target/TargetInstrInfo.h" > #include "llvm/Target/TargetRegisterInfo.h" > @@ -33,6 +34,12 @@ > > ScheduleDAG::~ScheduleDAG() {} > > +/// getInstrDesc helper to handle SDNodes. > +const TargetInstrDesc *ScheduleDAG::getNodeDesc(const SDNode *Node) const { > + if (!Node->isMachineOpcode()) return NULL; > + return &TII->get(Node->getMachineOpcode()); > +} > + > /// dump - dump the schedule. > void ScheduleDAG::dumpSchedule() const { > for (unsigned i = 0, e = Sequence.size(); i != e; i++) { > > Modified: llvm/trunk/lib/CodeGen/ScoreboardHazardRecognizer.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScoreboardHazardRecognizer.cpp?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/lib/CodeGen/ScoreboardHazardRecognizer.cpp (original) > +++ llvm/trunk/lib/CodeGen/ScoreboardHazardRecognizer.cpp Thu Dec 23 23:03:26 2010 > @@ -13,7 +13,7 @@ > // > //===----------------------------------------------------------------------===// > > -#define DEBUG_TYPE "sched-hazard" > +#define DEBUG_TYPE ::llvm::ScoreboardHazardRecognizer::DebugType > #include "llvm/CodeGen/ScoreboardHazardRecognizer.h" > #include "llvm/CodeGen/ScheduleDAG.h" > #include "llvm/Support/Debug.h" > @@ -23,29 +23,48 @@ > > using namespace llvm; > > +#ifndef NDEBUG > +const char *ScoreboardHazardRecognizer::DebugType = ""; > +#endif > + > ScoreboardHazardRecognizer:: > -ScoreboardHazardRecognizer(const InstrItineraryData *LItinData) : > - ScheduleHazardRecognizer(), ItinData(LItinData) { > +ScoreboardHazardRecognizer(const InstrItineraryData *II, > + const ScheduleDAG *SchedDAG, > + const char *ParentDebugType) : > + ScheduleHazardRecognizer(), ItinData(II), DAG(SchedDAG), IssueWidth(0), > + IssueCount(0) { > + > +#ifndef NDEBUG > + DebugType = ParentDebugType; > +#endif > + > // Determine the maximum depth of any itinerary. This determines the > // depth of the scoreboard. We always make the scoreboard at least 1 > // cycle deep to avoid dealing with the boundary condition. > unsigned ScoreboardDepth = 1; > if (ItinData && !ItinData->isEmpty()) { > + IssueWidth = ItinData->IssueWidth; > + > for (unsigned idx = 0; ; ++idx) { > if (ItinData->isEndMarker(idx)) > break; > > const InstrStage *IS = ItinData->beginStage(idx); > const InstrStage *E = ItinData->endStage(idx); > + unsigned CurCycle = 0; > unsigned ItinDepth = 0; > - for (; IS != E; ++IS) > - ItinDepth += IS->getCycles(); > + for (; IS != E; ++IS) { > + unsigned StageDepth = CurCycle + IS->getCycles(); > + if (ItinDepth < StageDepth) ItinDepth = StageDepth; > + CurCycle += IS->getNextCycles(); > + } > > // Find the next power-of-2 >= ItinDepth > while (ItinDepth > ScoreboardDepth) { > ScoreboardDepth *= 2; > } > } > + MaxLookAhead = ScoreboardDepth; > } > > ReservedScoreboard.reset(ScoreboardDepth); > @@ -56,6 +75,7 @@ > } > > void ScoreboardHazardRecognizer::Reset() { > + IssueCount = 0; > RequiredScoreboard.reset(); > ReservedScoreboard.reset(); > } > @@ -76,24 +96,46 @@ > } > } > > +bool ScoreboardHazardRecognizer::atIssueLimit() const { > + if (IssueWidth == 0) > + return false; > + > + return IssueCount == IssueWidth; > +} > + > ScheduleHazardRecognizer::HazardType > -ScoreboardHazardRecognizer::getHazardType(SUnit *SU) { > +ScoreboardHazardRecognizer::getHazardType(SUnit *SU, int Stalls) { > if (!ItinData || ItinData->isEmpty()) > return NoHazard; > > - unsigned cycle = 0; > + // Note that stalls will be negative for bottom-up scheduling. > + int cycle = Stalls; > > // Use the itinerary for the underlying instruction to check for > // free FU's in the scoreboard at the appropriate future cycles. > - unsigned idx = SU->getInstr()->getDesc().getSchedClass(); > + > + const TargetInstrDesc *TID = DAG->getInstrDesc(SU); > + if (TID == NULL) { > + // Don't check hazards for non-machineinstr Nodes. > + return NoHazard; > + } > + unsigned idx = TID->getSchedClass(); > for (const InstrStage *IS = ItinData->beginStage(idx), > *E = ItinData->endStage(idx); IS != E; ++IS) { > // We must find one of the stage's units free for every cycle the > // stage is occupied. FIXME it would be more accurate to find the > // same unit free in all the cycles. > for (unsigned int i = 0; i < IS->getCycles(); ++i) { > - assert(((cycle + i) < RequiredScoreboard.getDepth()) && > - "Scoreboard depth exceeded!"); > + int StageCycle = cycle + (int)i; > + if (StageCycle < 0) > + continue; > + > + if (StageCycle >= (int)RequiredScoreboard.getDepth()) { > + assert((StageCycle - Stalls) < (int)RequiredScoreboard.getDepth() && > + "Scoreboard depth exceeded!"); > + // This stage was stalled beyond pipeline depth, so cannot conflict. > + break; > + } > > unsigned freeUnits = IS->getUnits(); > switch (IS->getReservationKind()) { > @@ -101,18 +143,18 @@ > assert(0 && "Invalid FU reservation"); > case InstrStage::Required: > // Required FUs conflict with both reserved and required ones > - freeUnits &= ~ReservedScoreboard[cycle + i]; > + freeUnits &= ~ReservedScoreboard[StageCycle]; > // FALLTHROUGH > case InstrStage::Reserved: > // Reserved FUs can conflict only with required ones. > - freeUnits &= ~RequiredScoreboard[cycle + i]; > + freeUnits &= ~RequiredScoreboard[StageCycle]; > break; > } > > if (!freeUnits) { > DEBUG(dbgs() << "*** Hazard in cycle " << (cycle + i) << ", "); > DEBUG(dbgs() << "SU(" << SU->NodeNum << "): "); > - DEBUG(SU->getInstr()->dump()); > + DEBUG(DAG->dumpNode(SU)); > return Hazard; > } > } > @@ -128,11 +170,15 @@ > if (!ItinData || ItinData->isEmpty()) > return; > > + ++IssueCount; > + > unsigned cycle = 0; > > // Use the itinerary for the underlying instruction to reserve FU's > // in the scoreboard at the appropriate future cycles. > - unsigned idx = SU->getInstr()->getDesc().getSchedClass(); > + const TargetInstrDesc *TID = DAG->getInstrDesc(SU); > + assert(TID && "The scheduler must filter non-machineinstrs"); > + unsigned idx = TID->getSchedClass(); > for (const InstrStage *IS = ItinData->beginStage(idx), > *E = ItinData->endStage(idx); IS != E; ++IS) { > // We must reserve one of the stage's units for every cycle the > @@ -179,11 +225,13 @@ > } > > void ScoreboardHazardRecognizer::AdvanceCycle() { > + IssueCount = 0; > ReservedScoreboard[0] = 0; ReservedScoreboard.advance(); > RequiredScoreboard[0] = 0; RequiredScoreboard.advance(); > } > > void ScoreboardHazardRecognizer::RecedeCycle() { > + IssueCount = 0; > ReservedScoreboard[ReservedScoreboard.getDepth()-1] = 0; > ReservedScoreboard.recede(); > RequiredScoreboard[RequiredScoreboard.getDepth()-1] = 0; > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Thu Dec 23 23:03:26 2010 > @@ -63,11 +63,12 @@ > > public: > ScheduleDAGList(MachineFunction &mf, > - SchedulingPriorityQueue *availqueue, > - ScheduleHazardRecognizer *HR) > - : ScheduleDAGSDNodes(mf), > - AvailableQueue(availqueue), HazardRec(HR) { > - } > + SchedulingPriorityQueue *availqueue) > + : ScheduleDAGSDNodes(mf), AvailableQueue(availqueue) { > + > + const TargetMachine &tm = mf.getTarget(); > + HazardRec = tm.getInstrInfo()->CreateTargetHazardRecognizer(&tm, this); > + } > > ~ScheduleDAGList() { > delete HazardRec; > @@ -202,7 +203,7 @@ > SUnit *CurSUnit = AvailableQueue->pop(); > > ScheduleHazardRecognizer::HazardType HT = > - HazardRec->getHazardType(CurSUnit); > + HazardRec->getHazardType(CurSUnit, 0/*no stalls*/); > if (HT == ScheduleHazardRecognizer::NoHazard) { > FoundSUnit = CurSUnit; > break; > @@ -257,12 +258,8 @@ > // Public Constructor Functions > //===----------------------------------------------------------------------===// > > -/// createTDListDAGScheduler - This creates a top-down list scheduler with a > -/// new hazard recognizer. This scheduler takes ownership of the hazard > -/// recognizer and deletes it when done. > +/// createTDListDAGScheduler - This creates a top-down list scheduler. > ScheduleDAGSDNodes * > llvm::createTDListDAGScheduler(SelectionDAGISel *IS, CodeGenOpt::Level) { > - return new ScheduleDAGList(*IS->MF, > - new LatencyPriorityQueue(), > - IS->CreateTargetHazardRecognizer()); > + return new ScheduleDAGList(*IS->MF, new LatencyPriorityQueue()); > } > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Thu Dec 23 23:03:26 2010 > @@ -20,6 +20,7 @@ > #include "llvm/InlineAsm.h" > #include "llvm/CodeGen/SchedulerRegistry.h" > #include "llvm/CodeGen/SelectionDAGISel.h" > +#include "llvm/CodeGen/ScheduleHazardRecognizer.h" > #include "llvm/Target/TargetRegisterInfo.h" > #include "llvm/Target/TargetData.h" > #include "llvm/Target/TargetMachine.h" > @@ -65,6 +66,11 @@ > "which tries to balance ILP and register pressure", > createILPListDAGScheduler); > > +static cl::opt EnableSchedCycles( > + "enable-sched-cycles", > + cl::desc("Enable cycle-level precision during preRA scheduling"), > + cl::init(false), cl::Hidden); > + > namespace { > //===----------------------------------------------------------------------===// > /// ScheduleDAGRRList - The actual register reduction list scheduler > @@ -83,9 +89,21 @@ > /// AvailableQueue - The priority queue to use for the available SUnits. > SchedulingPriorityQueue *AvailableQueue; > > + /// PendingQueue - This contains all of the instructions whose operands have > + /// been issued, but their results are not ready yet (due to the latency of > + /// the operation). Once the operands becomes available, the instruction is > + /// added to the AvailableQueue. > + std::vector PendingQueue; > + > + /// HazardRec - The hazard recognizer to use. > + ScheduleHazardRecognizer *HazardRec; > + > /// CurCycle - The current scheduler state corresponds to this cycle. > unsigned CurCycle; > > + /// MinAvailableCycle - Cycle of the soonest available instruction. > + unsigned MinAvailableCycle; > + > /// 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. > @@ -98,14 +116,22 @@ > ScheduleDAGTopologicalSort Topo; > > public: > - ScheduleDAGRRList(MachineFunction &mf, > - bool isbottomup, bool needlatency, > - SchedulingPriorityQueue *availqueue) > - : ScheduleDAGSDNodes(mf), isBottomUp(isbottomup), NeedLatency(needlatency), > - AvailableQueue(availqueue), CurCycle(0), Topo(SUnits) { > - } > + ScheduleDAGRRList(MachineFunction &mf, bool needlatency, > + SchedulingPriorityQueue *availqueue, > + CodeGenOpt::Level OptLevel) > + : ScheduleDAGSDNodes(mf), isBottomUp(availqueue->isBottomUp()), > + NeedLatency(needlatency), AvailableQueue(availqueue), CurCycle(0), > + Topo(SUnits) { > + > + const TargetMachine &tm = mf.getTarget(); > + if (EnableSchedCycles && OptLevel != CodeGenOpt::None) > + HazardRec = tm.getInstrInfo()->CreateTargetHazardRecognizer(&tm, this); > + else > + HazardRec = new ScheduleHazardRecognizer(); > + } > > ~ScheduleDAGRRList() { > + delete HazardRec; > delete AvailableQueue; > } > > @@ -139,20 +165,31 @@ > } > > private: > + bool isReady(SUnit *SU) { > + return !EnableSchedCycles || !AvailableQueue->hasReadyFilter() || > + AvailableQueue->isReady(SU); > + } > + > void ReleasePred(SUnit *SU, const SDep *PredEdge); > void ReleasePredecessors(SUnit *SU); > void ReleaseSucc(SUnit *SU, const SDep *SuccEdge); > void ReleaseSuccessors(SUnit *SU); > - void CapturePred(SDep *PredEdge); > + void ReleasePending(); > + void AdvanceToCycle(unsigned NextCycle); > + void AdvancePastStalls(SUnit *SU); > + void EmitNode(SUnit *SU); > void ScheduleNodeBottomUp(SUnit*); > + void CapturePred(SDep *PredEdge); > void UnscheduleNodeBottomUp(SUnit*); > - void BacktrackBottomUp(SUnit*, unsigned); > + void RestoreHazardCheckerBottomUp(); > + void BacktrackBottomUp(SUnit*, SUnit*); > SUnit *CopyAndMoveSuccessors(SUnit*); > void InsertCopiesAndMoveSuccs(SUnit*, unsigned, > const TargetRegisterClass*, > const TargetRegisterClass*, > SmallVector&); > bool DelayForLiveRegsBottomUp(SUnit*, SmallVector&); > + > SUnit *PickNodeToScheduleBottomUp(); > void ListScheduleBottomUp(); > > @@ -198,6 +235,7 @@ > << " '" << BB->getName() << "' **********\n"); > > CurCycle = 0; > + MinAvailableCycle = EnableSchedCycles ? UINT_MAX : 0; > NumLiveRegs = 0; > LiveRegDefs.resize(TRI->getNumRegs(), NULL); > LiveRegGens.resize(TRI->getNumRegs(), NULL); > @@ -211,6 +249,8 @@ > > AvailableQueue->initNodes(SUnits); > > + HazardRec->Reset(); > + > // Execute the actual scheduling loop Top-Down or Bottom-Up as appropriate. > if (isBottomUp) > ListScheduleBottomUp(); > @@ -249,7 +289,20 @@ > // to be scheduled. Ignore the special EntrySU node. > if (PredSU->NumSuccsLeft == 0 && PredSU != &EntrySU) { > PredSU->isAvailable = true; > - AvailableQueue->push(PredSU); > + > + unsigned Height = PredSU->getHeight(); > + if (Height < MinAvailableCycle) > + MinAvailableCycle = Height; > + > + if (isReady(SU)) { > + AvailableQueue->push(PredSU); > + } > + // CapturePred and others may have left the node in the pending queue, avoid > + // adding it twice. > + else if (!PredSU->isPending) { > + PredSU->isPending = true; > + PendingQueue.push_back(PredSU); > + } > } > } > > @@ -292,6 +345,127 @@ > } > } > > +/// Check to see if any of the pending instructions are ready to issue. If > +/// so, add them to the available queue. > +void ScheduleDAGRRList::ReleasePending() { > + assert(!EnableSchedCycles && "requires --enable-sched-cycles" ); > + > + // If the available queue is empty, it is safe to reset MinAvailableCycle. > + if (AvailableQueue->empty()) > + MinAvailableCycle = UINT_MAX; > + > + // Check to see if any of the pending instructions are ready to issue. If > + // so, add them to the available queue. > + for (unsigned i = 0, e = PendingQueue.size(); i != e; ++i) { > + unsigned ReadyCycle = > + isBottomUp ? PendingQueue[i]->getHeight() : PendingQueue[i]->getDepth(); > + if (ReadyCycle < MinAvailableCycle) > + MinAvailableCycle = ReadyCycle; > + > + if (PendingQueue[i]->isAvailable) { > + if (!isReady(PendingQueue[i])) > + continue; > + AvailableQueue->push(PendingQueue[i]); > + } > + PendingQueue[i]->isPending = false; > + PendingQueue[i] = PendingQueue.back(); > + PendingQueue.pop_back(); > + --i; --e; > + } > +} > + > +/// Move the scheduler state forward by the specified number of Cycles. > +void ScheduleDAGRRList::AdvanceToCycle(unsigned NextCycle) { > + if (NextCycle <= CurCycle) > + return; > + > + AvailableQueue->setCurCycle(NextCycle); > + if (HazardRec->getMaxLookAhead() == 0) { > + // Bypass lots of virtual calls in case of long latency. > + CurCycle = NextCycle; > + } > + else { > + for (; CurCycle != NextCycle; ++CurCycle) { > + if (isBottomUp) > + HazardRec->RecedeCycle(); > + else > + HazardRec->AdvanceCycle(); > + } > + } > + // FIXME: Instead of visiting the pending Q each time, set a dirty flag on the > + // available Q to release pending nodes at least once before popping. > + ReleasePending(); > +} > + > +/// Move the scheduler state forward until the specified node's dependents are > +/// ready and can be scheduled with no resource conflicts. > +void ScheduleDAGRRList::AdvancePastStalls(SUnit *SU) { > + if (!EnableSchedCycles) > + return; > + > + unsigned ReadyCycle = isBottomUp ? SU->getHeight() : SU->getDepth(); > + > + // Bump CurCycle to account for latency. We assume the latency of other > + // available instructions may be hidden by the stall (not a full pipe stall). > + // This updates the hazard recognizer's cycle before reserving resources for > + // this instruction. > + AdvanceToCycle(ReadyCycle); > + > + // Calls are scheduled in their preceding cycle, so don't conflict with > + // hazards from instructions after the call. EmitNode will reset the > + // scoreboard state before emitting the call. > + if (isBottomUp && SU->isCall) > + return; > + > + // FIXME: For resource conflicts in very long non-pipelined stages, we > + // should probably skip ahead here to avoid useless scoreboard checks. > + int Stalls = 0; > + while (true) { > + ScheduleHazardRecognizer::HazardType HT = > + HazardRec->getHazardType(SU, isBottomUp ? -Stalls : Stalls); > + > + if (HT == ScheduleHazardRecognizer::NoHazard) > + break; > + > + ++Stalls; > + } > + AdvanceToCycle(CurCycle + Stalls); > +} > + > +/// Record this SUnit in the HazardRecognizer. > +/// Does not update CurCycle. > +void ScheduleDAGRRList::EmitNode(SUnit *SU) { > + switch (SU->getNode()->getOpcode()) { > + default: > + assert(SU->getNode()->isMachineOpcode() && > + "This target-independent node should not be scheduled."); > + break; > + case ISD::MERGE_VALUES: > + case ISD::TokenFactor: > + case ISD::CopyToReg: > + case ISD::CopyFromReg: > + case ISD::EH_LABEL: > + // Noops don't affect the scoreboard state. Copies are likely to be > + // removed. > + return; > + case ISD::INLINEASM: > + // For inline asm, clear the pipeline state. > + HazardRec->Reset(); > + return; > + } > + if (isBottomUp && SU->isCall) { > + // Calls are scheduled with their preceding instructions. For bottom-up > + // scheduling, clear the pipeline state before emitting. > + HazardRec->Reset(); > + } > + > + HazardRec->EmitInstruction(SU); > + > + if (!isBottomUp && SU->isCall) { > + HazardRec->Reset(); > + } > +} > + > /// 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. > @@ -304,8 +478,15 @@ > DEBUG(dbgs() << " Height [" << SU->getHeight() << "] pipeline stall!\n"); > #endif > > - // FIXME: Handle noop hazard. > + // FIXME: Do not modify node height. It may interfere with > + // backtracking. Instead add a "ready cycle" to SUnit. Before scheduling the > + // node it's ready cycle can aid heuristics, and after scheduling it can > + // indicate the scheduled cycle. > SU->setHeightToAtLeast(CurCycle); > + > + // Reserve resources for the scheduled intruction. > + EmitNode(SU); > + > Sequence.push_back(SU); > > AvailableQueue->ScheduledNode(SU); > @@ -327,6 +508,15 @@ > } > > SU->isScheduled = true; > + > + // Conditions under which the scheduler should eagerly advance the cycle: > + // (1) No available instructions > + // (2) All pipelines full, so available instructions must have hazards. > + // > + // If SchedCycles is disabled, count each inst as one cycle. > + if (!EnableSchedCycles || > + AvailableQueue->empty() || HazardRec->atIssueLimit()) > + AdvanceToCycle(CurCycle + 1); > } > > /// CapturePred - This does the opposite of ReleasePred. Since SU is being > @@ -377,31 +567,69 @@ > LiveRegGens[I->getReg()] = I->getSUnit(); > } > } > + if (SU->getHeight() < MinAvailableCycle) > + MinAvailableCycle = SU->getHeight(); > > SU->setHeightDirty(); > SU->isScheduled = false; > SU->isAvailable = true; > - AvailableQueue->push(SU); > + if (EnableSchedCycles && AvailableQueue->hasReadyFilter()) { > + // Don't make available until backtracking is complete. > + SU->isPending = true; > + PendingQueue.push_back(SU); > + } > + else { > + AvailableQueue->push(SU); > + } > AvailableQueue->UnscheduledNode(SU); > } > > +/// After backtracking, the hazard checker needs to be restored to a state > +/// corresponding the the current cycle. > +void ScheduleDAGRRList::RestoreHazardCheckerBottomUp() { > + HazardRec->Reset(); > + > + unsigned LookAhead = std::min((unsigned)Sequence.size(), > + HazardRec->getMaxLookAhead()); > + if (LookAhead == 0) > + return; > + > + std::vector::const_iterator I = (Sequence.end() - LookAhead); > + unsigned HazardCycle = (*I)->getHeight(); > + for (std::vector::const_iterator E = Sequence.end(); I != E; ++I) { > + SUnit *SU = *I; > + for (; SU->getHeight() > HazardCycle; ++HazardCycle) { > + HazardRec->RecedeCycle(); > + } > + EmitNode(SU); > + } > +} > + > /// BacktrackBottomUp - Backtrack scheduling to a previous cycle specified in > /// BTCycle in order to schedule a specific node. > -void ScheduleDAGRRList::BacktrackBottomUp(SUnit *SU, unsigned BtCycle) { > - SUnit *OldSU = NULL; > - while (CurCycle > BtCycle) { > - OldSU = Sequence.back(); > +void ScheduleDAGRRList::BacktrackBottomUp(SUnit *SU, SUnit *BtSU) { > + SUnit *OldSU = Sequence.back(); > + while (true) { > Sequence.pop_back(); > if (SU->isSucc(OldSU)) > // Don't try to remove SU from AvailableQueue. > SU->isAvailable = false; > + // FIXME: use ready cycle instead of height > + CurCycle = OldSU->getHeight(); > UnscheduleNodeBottomUp(OldSU); > - --CurCycle; > AvailableQueue->setCurCycle(CurCycle); > + if (OldSU == BtSU) > + break; > + OldSU = Sequence.back(); > } > > assert(!SU->isSucc(OldSU) && "Something is wrong!"); > > + RestoreHazardCheckerBottomUp(); > + > + if (EnableSchedCycles) > + ReleasePending(); > + > ++NumBacktracks; > } > > @@ -741,7 +969,7 @@ > > /// Return a node that can be scheduled in this cycle. Requirements: > /// (1) Ready: latency has been satisfied > -/// (2) No Hazards: resources are available (TBD) > +/// (2) No Hazards: resources are available > /// (3) No Interferences: may unschedule to break register interferences. > SUnit *ScheduleDAGRRList::PickNodeToScheduleBottomUp() { > SmallVector Interferences; > @@ -777,24 +1005,26 @@ > > // Try unscheduling up to the point where it's safe to schedule > // this node. > - unsigned LiveCycle = CurCycle; > + SUnit *BtSU = NULL; > + unsigned LiveCycle = UINT_MAX; > for (unsigned j = 0, ee = LRegs.size(); j != ee; ++j) { > unsigned Reg = LRegs[j]; > - unsigned LCycle = LiveRegGens[Reg]->getHeight(); > - LiveCycle = std::min(LiveCycle, LCycle); > + if (LiveRegGens[Reg]->getHeight() < LiveCycle) { > + BtSU = LiveRegGens[Reg]; > + LiveCycle = BtSU->getHeight(); > + } > } > - SUnit *OldSU = Sequence[LiveCycle]; > - if (!WillCreateCycle(TrySU, OldSU)) { > - BacktrackBottomUp(TrySU, LiveCycle); > + if (!WillCreateCycle(TrySU, BtSU)) { > + BacktrackBottomUp(TrySU, BtSU); > > // 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); > + if (BtSU->isAvailable) { > + BtSU->isAvailable = false; > + if (!BtSU->isPending) > + AvailableQueue->remove(BtSU); > } > - AddPred(TrySU, SDep(OldSU, SDep::Order, /*Latency=*/1, > + AddPred(TrySU, SDep(BtSU, SDep::Order, /*Latency=*/1, > /*Reg=*/0, /*isNormalMemory=*/false, > /*isMustAlias=*/false, /*isArtificial=*/true)); > > @@ -891,15 +1121,22 @@ > // priority. If it is not ready put it back. Schedule the node. > Sequence.reserve(SUnits.size()); > while (!AvailableQueue->empty()) { > + DEBUG(dbgs() << "\n*** Examining Available\n"; > + AvailableQueue->dump(this)); > + > // Pick the best node to schedule taking all constraints into > // consideration. > SUnit *SU = PickNodeToScheduleBottomUp(); > > - if (SU) > - ScheduleNodeBottomUp(SU); > + AdvancePastStalls(SU); > > - ++CurCycle; > - AvailableQueue->setCurCycle(CurCycle); > + ScheduleNodeBottomUp(SU); > + > + while (AvailableQueue->empty() && !PendingQueue.empty()) { > + // Advance the cycle to free resources. Skip ahead to the next ready SU. > + assert(MinAvailableCycle < UINT_MAX && "MinAvailableCycle uninitialized"); > + AdvanceToCycle(std::max(CurCycle + 1, MinAvailableCycle)); > + } > } > > // Reverse the order if it is bottom up. > @@ -967,7 +1204,6 @@ > /// ListScheduleTopDown - The main loop of list scheduling for top-down > /// schedulers. > void ScheduleDAGRRList::ListScheduleTopDown() { > - unsigned CurCycle = 0; > AvailableQueue->setCurCycle(CurCycle); > > // Release any successors of the special Entry node. > @@ -1011,9 +1247,18 @@ > template > class RegReductionPriorityQueue; > > + struct queue_sort : public std::binary_function { > + bool isReady(SUnit* SU, unsigned CurCycle) const { return true; } > + }; > + > /// bu_ls_rr_sort - Priority function for bottom up register pressure > // reduction scheduler. > - struct bu_ls_rr_sort : public std::binary_function { > + struct bu_ls_rr_sort : public queue_sort { > + enum { > + IsBottomUp = true, > + HasReadyFilter = false > + }; > + > RegReductionPriorityQueue *SPQ; > bu_ls_rr_sort(RegReductionPriorityQueue *spq) : SPQ(spq) {} > bu_ls_rr_sort(const bu_ls_rr_sort &RHS) : SPQ(RHS.SPQ) {} > @@ -1023,8 +1268,13 @@ > > // td_ls_rr_sort - Priority function for top down register pressure reduction > // scheduler. > - struct td_ls_rr_sort : public std::binary_function { > - RegReductionPriorityQueue *SPQ; > + struct td_ls_rr_sort : public queue_sort { > + enum { > + IsBottomUp = false, > + HasReadyFilter = false > + }; > + > + RegReductionPriorityQueue *SPQ; > td_ls_rr_sort(RegReductionPriorityQueue *spq) : SPQ(spq) {} > td_ls_rr_sort(const td_ls_rr_sort &RHS) : SPQ(RHS.SPQ) {} > > @@ -1032,7 +1282,12 @@ > }; > > // src_ls_rr_sort - Priority function for source order scheduler. > - struct src_ls_rr_sort : public std::binary_function { > + struct src_ls_rr_sort : public queue_sort { > + enum { > + IsBottomUp = true, > + HasReadyFilter = false > + }; > + > RegReductionPriorityQueue *SPQ; > src_ls_rr_sort(RegReductionPriorityQueue *spq) > : SPQ(spq) {} > @@ -1043,7 +1298,12 @@ > }; > > // hybrid_ls_rr_sort - Priority function for hybrid scheduler. > - struct hybrid_ls_rr_sort : public std::binary_function { > + struct hybrid_ls_rr_sort : public queue_sort { > + enum { > + IsBottomUp = true, > + HasReadyFilter = false > + }; > + > RegReductionPriorityQueue *SPQ; > hybrid_ls_rr_sort(RegReductionPriorityQueue *spq) > : SPQ(spq) {} > @@ -1055,13 +1315,20 @@ > > // ilp_ls_rr_sort - Priority function for ILP (instruction level parallelism) > // scheduler. > - struct ilp_ls_rr_sort : public std::binary_function { > + struct ilp_ls_rr_sort : public queue_sort { > + enum { > + IsBottomUp = true, > + HasReadyFilter = true > + }; > + > RegReductionPriorityQueue *SPQ; > ilp_ls_rr_sort(RegReductionPriorityQueue *spq) > : SPQ(spq) {} > ilp_ls_rr_sort(const ilp_ls_rr_sort &RHS) > : SPQ(RHS.SPQ) {} > > + bool isReady(SUnit *SU, unsigned CurCycle) const; > + > bool operator()(const SUnit* left, const SUnit* right) const; > }; > } // end anonymous namespace > @@ -1098,6 +1365,19 @@ > namespace { > template > class RegReductionPriorityQueue : public SchedulingPriorityQueue { > + static SUnit *popFromQueue(std::vector &Q, SF &Picker) { > + std::vector::iterator Best = Q.begin(); > + for (std::vector::iterator I = llvm::next(Q.begin()), > + E = Q.end(); I != E; ++I) > + if (Picker(*Best, *I)) > + Best = I; > + SUnit *V = *Best; > + if (Best != prior(Q.end())) > + std::swap(*Best, Q.back()); > + Q.pop_back(); > + return V; > + } > + > std::vector Queue; > SF Picker; > unsigned CurQueueId; > @@ -1130,7 +1410,8 @@ > const TargetInstrInfo *tii, > const TargetRegisterInfo *tri, > const TargetLowering *tli) > - : Picker(this), CurQueueId(0), TracksRegPressure(tracksrp), > + : SchedulingPriorityQueue(SF::HasReadyFilter), Picker(this), > + CurQueueId(0), TracksRegPressure(tracksrp), > MF(mf), TII(tii), TRI(tri), TLI(tli), scheduleDAG(NULL) { > if (TracksRegPressure) { > unsigned NumRC = TRI->getNumRegClasses(); > @@ -1144,6 +1425,8 @@ > } > } > > + bool isBottomUp() const { return SF::IsBottomUp; } > + > void initNodes(std::vector &sunits) { > SUnits = &sunits; > // Add pseudo dependency edges for two-address nodes. > @@ -1205,6 +1488,10 @@ > > bool empty() const { return Queue.empty(); } > > + bool isReady(SUnit *U) const { > + return Picker.HasReadyFilter && Picker.isReady(U, getCurCycle()); > + } > + > void push(SUnit *U) { > assert(!U->NodeQueueId && "Node in the queue already"); > U->NodeQueueId = ++CurQueueId; > @@ -1212,16 +1499,9 @@ > } > > SUnit *pop() { > - if (empty()) return NULL; > - std::vector::iterator Best = Queue.begin(); > - for (std::vector::iterator I = llvm::next(Queue.begin()), > - E = Queue.end(); I != E; ++I) > - if (Picker(*Best, *I)) > - Best = I; > - SUnit *V = *Best; > - if (Best != prior(Queue.end())) > - std::swap(*Best, Queue.back()); > - Queue.pop_back(); > + if (Queue.empty()) return NULL; > + > + SUnit *V = popFromQueue(Queue, Picker); > V->NodeQueueId = 0; > return V; > } > @@ -1475,6 +1755,20 @@ > } > } > > + void dump(ScheduleDAG *DAG) const { > + // Emulate pop() without clobbering NodeQueueIds. > + std::vector DumpQueue = Queue; > + SF DumpPicker = Picker; > + while (!DumpQueue.empty()) { > + SUnit *SU = popFromQueue(DumpQueue, DumpPicker); > + if (isBottomUp()) > + dbgs() << "Height " << SU->getHeight() << ": "; > + else > + dbgs() << "Depth " << SU->getDepth() << ": "; > + SU->dump(DAG); > + } > + } > + > protected: > bool canClobber(const SUnit *SU, const SUnit *Op); > void AddPseudoTwoAddrDeps(); > @@ -1605,6 +1899,7 @@ > if (LScratch != RScratch) > return LScratch > RScratch; > > + // Note: with a bottom-up ready filter, the height check may be redundant. > if (left->getHeight() != right->getHeight()) > return left->getHeight() > right->getHeight(); > > @@ -1696,6 +1991,12 @@ > return BURRSort(left, right, SPQ); > } > > +// Schedule as many instructions in each cycle as possible. So don't make an > +// instruction available unless it is ready in the current cycle. > +bool ilp_ls_rr_sort::isReady(SUnit *SU, unsigned CurCycle) const { > + return SU->getHeight() <= CurCycle; > +} > + > bool ilp_ls_rr_sort::operator()(const SUnit *left, > const SUnit *right) const { > if (left->isCall || right->isCall) > @@ -2051,46 +2352,50 @@ > //===----------------------------------------------------------------------===// > > llvm::ScheduleDAGSDNodes * > -llvm::createBURRListDAGScheduler(SelectionDAGISel *IS, CodeGenOpt::Level) { > +llvm::createBURRListDAGScheduler(SelectionDAGISel *IS, > + CodeGenOpt::Level OptLevel) { > 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); > + ScheduleDAGRRList *SD = new ScheduleDAGRRList(*IS->MF, false, PQ, OptLevel); > PQ->setScheduleDAG(SD); > return SD; > } > > llvm::ScheduleDAGSDNodes * > -llvm::createTDRRListDAGScheduler(SelectionDAGISel *IS, CodeGenOpt::Level) { > +llvm::createTDRRListDAGScheduler(SelectionDAGISel *IS, > + CodeGenOpt::Level OptLevel) { > 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); > + ScheduleDAGRRList *SD = new ScheduleDAGRRList(*IS->MF, false, PQ, OptLevel); > PQ->setScheduleDAG(SD); > return SD; > } > > llvm::ScheduleDAGSDNodes * > -llvm::createSourceListDAGScheduler(SelectionDAGISel *IS, CodeGenOpt::Level) { > +llvm::createSourceListDAGScheduler(SelectionDAGISel *IS, > + CodeGenOpt::Level OptLevel) { > 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); > + ScheduleDAGRRList *SD = new ScheduleDAGRRList(*IS->MF, false, PQ, OptLevel); > PQ->setScheduleDAG(SD); > return SD; > } > > llvm::ScheduleDAGSDNodes * > -llvm::createHybridListDAGScheduler(SelectionDAGISel *IS, CodeGenOpt::Level) { > +llvm::createHybridListDAGScheduler(SelectionDAGISel *IS, > + CodeGenOpt::Level OptLevel) { > const TargetMachine &TM = IS->TM; > const TargetInstrInfo *TII = TM.getInstrInfo(); > const TargetRegisterInfo *TRI = TM.getRegisterInfo(); > @@ -2098,13 +2403,15 @@ > > HybridBURRPriorityQueue *PQ = > new HybridBURRPriorityQueue(*IS->MF, true, TII, TRI, TLI); > - ScheduleDAGRRList *SD = new ScheduleDAGRRList(*IS->MF, true, true, PQ); > + > + ScheduleDAGRRList *SD = new ScheduleDAGRRList(*IS->MF, true, PQ, OptLevel); > PQ->setScheduleDAG(SD); > return SD; > } > > llvm::ScheduleDAGSDNodes * > -llvm::createILPListDAGScheduler(SelectionDAGISel *IS, CodeGenOpt::Level) { > +llvm::createILPListDAGScheduler(SelectionDAGISel *IS, > + CodeGenOpt::Level OptLevel) { > const TargetMachine &TM = IS->TM; > const TargetInstrInfo *TII = TM.getInstrInfo(); > const TargetRegisterInfo *TRI = TM.getRegisterInfo(); > @@ -2112,7 +2419,7 @@ > > ILPBURRPriorityQueue *PQ = > new ILPBURRPriorityQueue(*IS->MF, true, TII, TRI, TLI); > - ScheduleDAGRRList *SD = new ScheduleDAGRRList(*IS->MF, true, true, PQ); > + ScheduleDAGRRList *SD = new ScheduleDAGRRList(*IS->MF, true, PQ, OptLevel); > PQ->setScheduleDAG(SD); > return SD; > } > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Dec 23 23:03:26 2010 > @@ -1201,10 +1201,6 @@ > return Ctor(this, OptLevel); > } > > -ScheduleHazardRecognizer *SelectionDAGISel::CreateTargetHazardRecognizer() { > - return new ScheduleHazardRecognizer(); > -} > - > //===----------------------------------------------------------------------===// > // Helper functions used by the generated instruction selector. > //===----------------------------------------------------------------------===// > > Modified: llvm/trunk/lib/CodeGen/TargetInstrInfoImpl.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetInstrInfoImpl.cpp?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/lib/CodeGen/TargetInstrInfoImpl.cpp (original) > +++ llvm/trunk/lib/CodeGen/TargetInstrInfoImpl.cpp Thu Dec 23 23:03:26 2010 > @@ -414,8 +414,18 @@ > return false; > } > > +// Default implementation of CreateTargetPreRAHazardRecognizer. > +ScheduleHazardRecognizer *TargetInstrInfoImpl:: > +CreateTargetHazardRecognizer(const TargetMachine *TM, > + const ScheduleDAG *DAG) const { > + // Dummy hazard recognizer allows all instructions to issue. > + return new ScheduleHazardRecognizer(); > +} > + > // Default implementation of CreateTargetPostRAHazardRecognizer. > ScheduleHazardRecognizer *TargetInstrInfoImpl:: > -CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II) const { > - return (ScheduleHazardRecognizer *)new ScoreboardHazardRecognizer(II); > +CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, > + const ScheduleDAG *DAG) const { > + return (ScheduleHazardRecognizer *) > + new ScoreboardHazardRecognizer(II, DAG, "post-RA-sched"); > } > > Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Thu Dec 23 23:03:26 2010 > @@ -41,6 +41,13 @@ > EnableARM3Addr("enable-arm-3-addr-conv", cl::Hidden, > cl::desc("Enable ARM 2-addr to 3-addr conv")); > > +// Other targets already have a hazard recognizer enabled by default, so this > +// flag currently only affects ARM. It will be generalized when it becomes a > +// disabled flag. > +static cl::opt EnableHazardRecognizer( > + "enable-sched-hazard", cl::Hidden, > + cl::desc("Enable hazard detection during preRA scheduling"), > + cl::init(false)); > > /// ARM_MLxEntry - Record information about MLA / MLS instructions. > struct ARM_MLxEntry { > @@ -85,12 +92,25 @@ > } > } > > +// Use a ScoreboardHazardRecognizer for prepass ARM scheduling. TargetInstrImpl > +// currently defaults to no prepass hazard recognizer. > ScheduleHazardRecognizer *ARMBaseInstrInfo:: > -CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II) const { > +CreateTargetHazardRecognizer(const TargetMachine *TM, > + const ScheduleDAG *DAG) const { > + if (EnableHazardRecognizer) { > + const InstrItineraryData *II = TM->getInstrItineraryData(); > + return new ScoreboardHazardRecognizer(II, DAG, "pre-RA-sched"); > + } > + return TargetInstrInfoImpl::CreateTargetHazardRecognizer(TM, DAG); > +} > + > +ScheduleHazardRecognizer *ARMBaseInstrInfo:: > +CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, > + const ScheduleDAG *DAG) const { > if (Subtarget.isThumb2() || Subtarget.hasVFP2()) > return (ScheduleHazardRecognizer *) > - new ARMHazardRecognizer(II, *this, getRegisterInfo(), Subtarget); > - return TargetInstrInfoImpl::CreateTargetPostRAHazardRecognizer(II); > + new ARMHazardRecognizer(II, *this, getRegisterInfo(), Subtarget, DAG); > + return TargetInstrInfoImpl::CreateTargetPostRAHazardRecognizer(II, DAG); > } > > MachineInstr * > > Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h Thu Dec 23 23:03:26 2010 > @@ -211,7 +211,12 @@ > const ARMSubtarget &getSubtarget() const { return Subtarget; } > > ScheduleHazardRecognizer * > - CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II) const; > + CreateTargetHazardRecognizer(const TargetMachine *TM, > + const ScheduleDAG *DAG) const; > + > + ScheduleHazardRecognizer * > + CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, > + const ScheduleDAG *DAG) const; > > // Branch analysis. > virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, > > Modified: llvm/trunk/lib/Target/ARM/ARMHazardRecognizer.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMHazardRecognizer.cpp?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMHazardRecognizer.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMHazardRecognizer.cpp Thu Dec 23 23:03:26 2010 > @@ -34,7 +34,9 @@ > } > > ScheduleHazardRecognizer::HazardType > -ARMHazardRecognizer::getHazardType(SUnit *SU) { > +ARMHazardRecognizer::getHazardType(SUnit *SU, int Stalls) { > + assert(Stalls == 0 && "ARM hazards don't support scoreboard lookahead"); > + > MachineInstr *MI = SU->getInstr(); > > if (!MI->isDebugValue()) { > @@ -61,19 +63,19 @@ > (TII.canCauseFpMLxStall(MI->getOpcode()) || > hasRAWHazard(DefMI, MI, TRI))) { > // Try to schedule another instruction for the next 4 cycles. > - if (Stalls == 0) > - Stalls = 4; > + if (FpMLxStalls == 0) > + FpMLxStalls = 4; > return Hazard; > } > } > } > > - return ScoreboardHazardRecognizer::getHazardType(SU); > + return ScoreboardHazardRecognizer::getHazardType(SU, Stalls); > } > > void ARMHazardRecognizer::Reset() { > LastMI = 0; > - Stalls = 0; > + FpMLxStalls = 0; > ITBlockSize = 0; > ScoreboardHazardRecognizer::Reset(); > } > @@ -100,14 +102,14 @@ > > if (!MI->isDebugValue()) { > LastMI = MI; > - Stalls = 0; > + FpMLxStalls = 0; > } > > ScoreboardHazardRecognizer::EmitInstruction(SU); > } > > void ARMHazardRecognizer::AdvanceCycle() { > - if (Stalls && --Stalls == 0) > + if (FpMLxStalls && --FpMLxStalls == 0) > // Stalled for 4 cycles but still can't schedule any other instructions. > LastMI = 0; > ScoreboardHazardRecognizer::AdvanceCycle(); > > Modified: llvm/trunk/lib/Target/ARM/ARMHazardRecognizer.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMHazardRecognizer.h?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMHazardRecognizer.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMHazardRecognizer.h Thu Dec 23 23:03:26 2010 > @@ -29,7 +29,7 @@ > const ARMSubtarget &STI; > > MachineInstr *LastMI; > - unsigned Stalls; > + unsigned FpMLxStalls; > unsigned ITBlockSize; // No. of MIs in current IT block yet to be scheduled. > MachineInstr *ITBlockMIs[4]; > > @@ -37,11 +37,12 @@ > ARMHazardRecognizer(const InstrItineraryData *ItinData, > const ARMBaseInstrInfo &tii, > const ARMBaseRegisterInfo &tri, > - const ARMSubtarget &sti) : > - ScoreboardHazardRecognizer(ItinData), TII(tii), TRI(tri), STI(sti), > - LastMI(0), ITBlockSize(0) {} > + const ARMSubtarget &sti, > + const ScheduleDAG *DAG) : > + ScoreboardHazardRecognizer(ItinData, DAG, "post-RA-sched"), TII(tii), > + TRI(tri), STI(sti), LastMI(0), ITBlockSize(0) {} > > - virtual HazardType getHazardType(SUnit *SU); > + virtual HazardType getHazardType(SUnit *SU, int Stalls); > virtual void Reset(); > virtual void EmitInstruction(SUnit *SU); > virtual void AdvanceCycle(); > > Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp Thu Dec 23 23:03:26 2010 > @@ -140,6 +140,9 @@ > FSWithArch = FS; > CPUString = ParseSubtargetFeatures(FSWithArch, CPUString); > > + // After parsing Itineraries, set ItinData.IssueWidth. > + computeIssueWidth(); > + > // Thumb2 implies at least V6T2. > if (ARMArchVersion >= V6T2) > ThumbMode = Thumb2; > @@ -224,6 +227,21 @@ > return 10; > } > > +void ARMSubtarget::computeIssueWidth() { > + unsigned allStage1Units = 0; > + for (const InstrItinerary *itin = InstrItins.Itineraries; > + itin->FirstStage != ~0U; ++itin) { > + const InstrStage *IS = InstrItins.Stages + itin->FirstStage; > + allStage1Units |= IS->getUnits(); > + } > + InstrItins.IssueWidth = 0; > + while (allStage1Units) { > + ++InstrItins.IssueWidth; > + // clear the lowest bit > + allStage1Units ^= allStage1Units & ~(allStage1Units - 1); > + } > +} > + > bool ARMSubtarget::enablePostRAScheduler( > CodeGenOpt::Level OptLevel, > TargetSubtarget::AntiDepBreakMode& Mode, > > Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.h?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMSubtarget.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMSubtarget.h Thu Dec 23 23:03:26 2010 > @@ -156,6 +156,8 @@ > std::string ParseSubtargetFeatures(const std::string &FS, > const std::string &CPU); > > + void computeIssueWidth(); > + > bool hasV4TOps() const { return ARMArchVersion >= V4T; } > bool hasV5TOps() const { return ARMArchVersion >= V5T; } > bool hasV5TEOps() const { return ARMArchVersion >= V5TE; } > > Modified: llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.cpp?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.cpp (original) > +++ llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.cpp Thu Dec 23 23:03:26 2010 > @@ -41,12 +41,14 @@ > /// > /// \return NoHazard > ScheduleHazardRecognizer::HazardType > -SPUHazardRecognizer::getHazardType(SUnit *SU) > +SPUHazardRecognizer::getHazardType(SUnit *SU, int Stalls) > { > // Initial thoughts on how to do this, but this code cannot work unless the > // function's prolog and epilog code are also being scheduled so that we can > // accurately determine which pipeline is being scheduled. > #if 0 > + assert(Stalls == 0 && "SPU hazards don't yet support scoreboard lookahead"); > + > const SDNode *Node = SU->getNode()->getFlaggedMachineNode(); > ScheduleHazardRecognizer::HazardType retval = NoHazard; > bool mustBeOdd = false; > > Modified: llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h (original) > +++ llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h Thu Dec 23 23:03:26 2010 > @@ -30,7 +30,7 @@ > > public: > SPUHazardRecognizer(const TargetInstrInfo &TII); > - virtual HazardType getHazardType(SUnit *SU); > + virtual HazardType getHazardType(SUnit *SU, int Stalls); > virtual void EmitInstruction(SUnit *SU); > virtual void AdvanceCycle(); > virtual void EmitNoop(); > > Modified: llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp (original) > +++ llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp Thu Dec 23 23:03:26 2010 > @@ -301,14 +301,6 @@ > return "Cell SPU DAG->DAG Pattern Instruction Selection"; > } > > - /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for > - /// this target when scheduling the DAG. > - virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer() { > - const TargetInstrInfo *II = TM.getInstrInfo(); > - assert(II && "No InstrInfo?"); > - return new SPUHazardRecognizer(*II); > - } > - > private: > SDValue getRC( MVT ); > > > Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp (original) > +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp Thu Dec 23 23:03:26 2010 > @@ -16,6 +16,7 @@ > #include "SPUInstrBuilder.h" > #include "SPUTargetMachine.h" > #include "SPUGenInstrInfo.inc" > +#include "SPUHazardRecognizers.h" > #include "llvm/CodeGen/MachineInstrBuilder.h" > #include "llvm/Support/Debug.h" > #include "llvm/Support/ErrorHandling.h" > @@ -54,6 +55,16 @@ > RI(*TM.getSubtargetImpl(), *this) > { /* NOP */ } > > +/// CreateTargetHazardRecognizer - Return the hazard recognizer to use for > +/// this target when scheduling the DAG. > +ScheduleHazardRecognizer *SPUInstrInfo::CreateTargetHazardRecognizer( > + const TargetMachine *TM, > + const ScheduleDAG *DAG) const { > + const TargetInstrInfo *TII = TM->getInstrInfo(); > + assert(TII && "No InstrInfo?"); > + return new SPUHazardRecognizer(*TII); > +} > + > unsigned > SPUInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, > int &FrameIndex) const { > > Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h (original) > +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h Thu Dec 23 23:03:26 2010 > @@ -32,6 +32,10 @@ > /// > virtual const SPURegisterInfo &getRegisterInfo() const { return RI; } > > + ScheduleHazardRecognizer * > + CreateTargetHazardRecognizer(const TargetMachine *TM, > + const ScheduleDAG *DAG) const; > + > unsigned isLoadFromStackSlot(const MachineInstr *MI, > int &FrameIndex) const; > unsigned isStoreToStackSlot(const MachineInstr *MI, > > Modified: llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp (original) > +++ llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp Thu Dec 23 23:03:26 2010 > @@ -122,7 +122,9 @@ > /// instructions that wouldn't terminate the dispatch group that would cause a > /// pipeline flush. > ScheduleHazardRecognizer::HazardType PPCHazardRecognizer970:: > -getHazardType(SUnit *SU) { > +getHazardType(SUnit *SU, int Stalls) { > + assert(Stalls == 0 && "PPC hazards don't support scoreboard lookahead"); > + > const SDNode *Node = SU->getNode()->getGluedMachineNode(); > bool isFirst, isSingle, isCracked, isLoad, isStore; > PPCII::PPC970_Unit InstrType = > > Modified: llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.h?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.h (original) > +++ llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.h Thu Dec 23 23:03:26 2010 > @@ -48,7 +48,7 @@ > > public: > PPCHazardRecognizer970(const TargetInstrInfo &TII); > - virtual HazardType getHazardType(SUnit *SU); > + virtual HazardType getHazardType(SUnit *SU, int Stalls); > virtual void EmitInstruction(SUnit *SU); > virtual void AdvanceCycle(); > > > Modified: llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp (original) > +++ llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Thu Dec 23 23:03:26 2010 > @@ -16,7 +16,6 @@ > #include "PPC.h" > #include "PPCPredicates.h" > #include "PPCTargetMachine.h" > -#include "PPCHazardRecognizers.h" > #include "llvm/CodeGen/MachineInstrBuilder.h" > #include "llvm/CodeGen/MachineFunction.h" > #include "llvm/CodeGen/MachineFunctionAnalysis.h" > @@ -155,16 +154,6 @@ > return "PowerPC DAG->DAG Pattern Instruction Selection"; > } > > - /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for > - /// this target when scheduling the DAG. > - virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer() { > - // Should use subtarget info to pick the right hazard recognizer. For > - // now, always return a PPC970 recognizer. > - const TargetInstrInfo *II = TM.getInstrInfo(); > - assert(II && "No InstrInfo?"); > - return new PPCHazardRecognizer970(*II); > - } > - > // Include the pieces autogenerated from the target description. > #include "PPCGenDAGISel.inc" > > > Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp (original) > +++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp Thu Dec 23 23:03:26 2010 > @@ -17,6 +17,7 @@ > #include "PPCPredicates.h" > #include "PPCGenInstrInfo.inc" > #include "PPCTargetMachine.h" > +#include "PPCHazardRecognizers.h" > #include "llvm/ADT/STLExtras.h" > #include "llvm/CodeGen/MachineFrameInfo.h" > #include "llvm/CodeGen/MachineInstrBuilder.h" > @@ -39,6 +40,18 @@ > : TargetInstrInfoImpl(PPCInsts, array_lengthof(PPCInsts)), TM(tm), > RI(*TM.getSubtargetImpl(), *this) {} > > +/// CreateTargetHazardRecognizer - Return the hazard recognizer to use for > +/// this target when scheduling the DAG. > +ScheduleHazardRecognizer *PPCInstrInfo::CreateTargetHazardRecognizer( > + const TargetMachine *TM, > + const ScheduleDAG *DAG) const { > + // Should use subtarget info to pick the right hazard recognizer. For > + // now, always return a PPC970 recognizer. > + const TargetInstrInfo *TII = TM->getInstrInfo(); > + assert(TII && "No InstrInfo?"); > + return new PPCHazardRecognizer970(*TII); > +} > + > unsigned PPCInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, > int &FrameIndex) const { > switch (MI->getOpcode()) { > > Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h?rev=122541&r1=122540&r2=122541&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h (original) > +++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h Thu Dec 23 23:03:26 2010 > @@ -82,6 +82,10 @@ > /// > virtual const PPCRegisterInfo &getRegisterInfo() const { return RI; } > > + ScheduleHazardRecognizer * > + CreateTargetHazardRecognizer(const TargetMachine *TM, > + const ScheduleDAG *DAG) const; > + > unsigned isLoadFromStackSlot(const MachineInstr *MI, > int &FrameIndex) const; > unsigned isStoreToStackSlot(const MachineInstr *MI, > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From atrick at apple.com Fri Dec 24 00:46:50 2010 From: atrick at apple.com (Andrew Trick) Date: Fri, 24 Dec 2010 06:46:50 -0000 Subject: [llvm-commits] [llvm] r122544 - in /llvm/trunk/lib/CodeGen: ScheduleDAG.cpp SelectionDAG/ScheduleDAGRRList.cpp Message-ID: <20101224064650.AF9462A6C12C@llvm.org> Author: atrick Date: Fri Dec 24 00:46:50 2010 New Revision: 122544 URL: http://llvm.org/viewvc/llvm-project?rev=122544&view=rev Log: Fix a few cases where the scheduler is not checking for phys reg copies. The scheduling node may have a NULL DAG node, yuck. Modified: llvm/trunk/lib/CodeGen/ScheduleDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/lib/CodeGen/ScheduleDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAG.cpp?rev=122544&r1=122543&r2=122544&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ScheduleDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/ScheduleDAG.cpp Fri Dec 24 00:46:50 2010 @@ -36,7 +36,7 @@ /// getInstrDesc helper to handle SDNodes. const TargetInstrDesc *ScheduleDAG::getNodeDesc(const SDNode *Node) const { - if (!Node->isMachineOpcode()) return NULL; + if (!Node || !Node->isMachineOpcode()) return NULL; return &TII->get(Node->getMachineOpcode()); } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=122544&r1=122543&r2=122544&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Fri Dec 24 00:46:50 2010 @@ -435,6 +435,13 @@ /// Record this SUnit in the HazardRecognizer. /// Does not update CurCycle. void ScheduleDAGRRList::EmitNode(SUnit *SU) { + if (!EnableSchedCycles || HazardRec->getMaxLookAhead() == 0) + return; + + // Check for phys reg copy. + if (!SU->getNode()) + return; + switch (SU->getNode()->getOpcode()) { default: assert(SU->getNode()->isMachineOpcode() && @@ -645,13 +652,13 @@ /// CopyAndMoveSuccessors - Clone the specified node and move its scheduled /// successors to the newly created node. SUnit *ScheduleDAGRRList::CopyAndMoveSuccessors(SUnit *SU) { - if (SU->getNode()->getGluedNode()) - return NULL; - SDNode *N = SU->getNode(); if (!N) return NULL; + if (SU->getNode()->getGluedNode()) + return NULL; + SUnit *NewSU; bool TryUnfold = false; for (unsigned i = 0, e = N->getNumValues(); i != e; ++i) { From atrick at apple.com Fri Dec 24 01:10:19 2010 From: atrick at apple.com (Andrew Trick) Date: Fri, 24 Dec 2010 07:10:19 -0000 Subject: [llvm-commits] [llvm] r122545 - in /llvm/trunk: include/llvm/CodeGen/ScheduleDAG.h lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Message-ID: <20101224071019.409C72A6C12C@llvm.org> Author: atrick Date: Fri Dec 24 01:10:19 2010 New Revision: 122545 URL: http://llvm.org/viewvc/llvm-project?rev=122545&view=rev Log: Minor cleanup related to my latest scheduler changes. Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=122545&r1=122544&r2=122545&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Fri Dec 24 01:10:19 2010 @@ -328,7 +328,7 @@ /// isInstr - Return true if this SUnit refers to a machine instruction as /// opposed to an SDNode. - bool isInstr() const { return !Node; } + bool isInstr() const { return Instr; } /// setInstr - Assign the instruction for the SUnit. /// This may be used during post-regalloc scheduling. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=122545&r1=122544&r2=122545&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Fri Dec 24 01:10:19 2010 @@ -348,7 +348,10 @@ /// Check to see if any of the pending instructions are ready to issue. If /// so, add them to the available queue. void ScheduleDAGRRList::ReleasePending() { - assert(!EnableSchedCycles && "requires --enable-sched-cycles" ); + if (!EnableSchedCycles) { + assert(PendingQueue.empty() && "pending instrs not allowed in this mode"); + return; + } // If the available queue is empty, it is safe to reset MinAvailableCycle. if (AvailableQueue->empty()) @@ -634,8 +637,7 @@ RestoreHazardCheckerBottomUp(); - if (EnableSchedCycles) - ReleasePending(); + ReleasePending(); ++NumBacktracks; } From geek4civic at gmail.com Fri Dec 24 02:32:42 2010 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Fri, 24 Dec 2010 17:32:42 +0900 Subject: [llvm-commits] [LLVMdev] LLVM on Cygwin: why tests don't run In-Reply-To: References: Message-ID: Good evening, Csaba! I think rather, Cygwin does not need to know what PATHEXT would be. A patch(0001) is attached. Another patch is for unittests. Lit does not find *Tests.exe in unittests on ToT. 2010/12/24 Csaba Raduly : > P.S. > With the above change, "make check-all" starts to run. Estimated run > time: 40 hours on my 1.8GHz single-core Centrino laptop. (The same > machine running Linux completed "make check-all" in 2min 30 sec!) me2. I don't know why too slow. It seems executable files would not hit in disk cache. FYI, try ;) (to warm cache) $ (cd Release+Asserts; mkdir xxx; mv -v *.exe *.dll xxx; cp -v xxx/* .; rm -rfv xxx) ...Takumi -------------- next part -------------- From 006ce1d5056c8c1e786885dc00df58b9a39b8f20 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sat, 21 Aug 2010 18:10:13 +0900 Subject: [PATCH 1/5] lit/Util.py: On Cygwin, 'PATHEXT' may exist but it should not be used. --- utils/lit/lit/Util.py | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/utils/lit/lit/Util.py b/utils/lit/lit/Util.py index 414b714..611b5bb 100644 --- a/utils/lit/lit/Util.py +++ b/utils/lit/lit/Util.py @@ -64,7 +64,11 @@ def which(command, paths = None): paths = os.defpath # Get suffixes to search. - pathext = os.environ.get('PATHEXT', '').split(os.pathsep) + # On Cygwin, 'PATHEXT' may exist but it should not be used. + if os.pathsep == ';': + pathext = os.environ.get('PATHEXT', '').split(';') + else: + pathext = [''] # Search the paths... for path in paths.split(os.pathsep): -- 1.7.1.GIT -------------- next part -------------- From b02ee826b511f26dd99022d16aa3cceb80f79aec Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Tue, 24 Aug 2010 12:37:52 +0900 Subject: [PATCH 2/5] lit/TestFormats.py: Unittests may be found with suffix .exe also on Cygwin. --- utils/lit/lit/TestFormats.py | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/lit/lit/TestFormats.py b/utils/lit/lit/TestFormats.py index 230995a..6dda2fd 100644 --- a/utils/lit/lit/TestFormats.py +++ b/utils/lit/lit/TestFormats.py @@ -1,11 +1,11 @@ import os -import platform +import sys import Test import TestRunner import Util -kIsWindows = platform.system() == 'Windows' +kIsWindows = sys.platform in ['win32', 'cygwin'] class GoogleTest(object): def __init__(self, test_sub_dir, test_suffix): -- 1.7.1.GIT From benny.kra at googlemail.com Fri Dec 24 10:12:59 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Fri, 24 Dec 2010 17:12:59 +0100 Subject: [llvm-commits] [llvm] r122516 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp In-Reply-To: <20101223205735.3796C2A6C12C@llvm.org> References: <20101223205735.3796C2A6C12C@llvm.org> Message-ID: On 23.12.2010, at 21:57, Owen Anderson wrote: > Author: resistor > Date: Thu Dec 23 14:57:35 2010 > New Revision: 122516 > > URL: http://llvm.org/viewvc/llvm-project?rev=122516&view=rev > Log: > It is possible for SimplifyCFG to cause PHI nodes to become redundant too late in the optimization > pipeline to be caught by instcombine, and it's not feasible to catch them in SimplifyCFG because the > use-lists are in an inconsistent state at the point where it could know that it need to simplify them. > Instead, have CodeGenPrepare look for trivially redundant PHIs as part of its general cleanup effort. Would it hurt much if we ran SimplifyInstruction on all instructions, not just PHIs? I've seen SimplifyCFG producing other nonsense like "%y = or i1 false, %x" too. From daniel at zuster.org Fri Dec 24 10:41:46 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Fri, 24 Dec 2010 16:41:46 -0000 Subject: [llvm-commits] [llvm] r122547 - in /llvm/trunk: lib/MC/MachObjectWriter.cpp test/MC/MachO/darwin-Thumb-reloc.s Message-ID: <20101224164146.766312A6C12C@llvm.org> Author: ddunbar Date: Fri Dec 24 10:41:46 2010 New Revision: 122547 URL: http://llvm.org/viewvc/llvm-project?rev=122547&view=rev Log: MC/Mach-O/ARM: Start handling some Thumb branches. Added: llvm/trunk/test/MC/MachO/darwin-Thumb-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=122547&r1=122546&r2=122547&view=diff ============================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/MachObjectWriter.cpp Fri Dec 24 10:41:46 2010 @@ -931,6 +931,20 @@ // Report as 'long', even though that is not quite accurate. Log2Size = llvm::Log2_32(4); return true; + + // Handle Thumb branches. + case ARM::fixup_arm_thumb_br: + Log2Size = llvm::Log2_32(2); + return true; + + case ARM::fixup_arm_thumb_bl: + Log2Size = llvm::Log2_32(4); + return true; + + case ARM::fixup_arm_thumb_blx: + // 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, Added: llvm/trunk/test/MC/MachO/darwin-Thumb-reloc.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/darwin-Thumb-reloc.s?rev=122547&view=auto ============================================================================== --- llvm/trunk/test/MC/MachO/darwin-Thumb-reloc.s (added) +++ llvm/trunk/test/MC/MachO/darwin-Thumb-reloc.s Fri Dec 24 10:41:46 2010 @@ -0,0 +1,139 @@ +@ RUN: llvm-mc -n -triple thumbv7-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 + .section __TEXT,__text,regular,pure_instructions + .globl _main + .align 2 + .code 16 + .thumb_func _main +_main: +LPC0_0: + blx _printf + .align 2 +LCPI0_0: + .long L_.str-(LPC0_0+4) + + .section __TEXT,__cstring,cstring_literals + .align 2 +L_.str: + .asciz "s0" + +.subsections_via_symbols + +@ CHECK: ('cputype', 12) +@ CHECK: ('cpusubtype', 9) +@ CHECK: ('filetype', 1) +@ CHECK: ('num_load_commands', 3) +@ CHECK: ('load_commands_size', 296) +@ CHECK: ('flag', 8192) +@ CHECK: ('load_commands', [ +@ CHECK: # Load Command 0 +@ CHECK: (('command', 1) +@ CHECK: ('size', 192) +@ 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', 11) +@ CHECK: ('file_offset', 324) +@ CHECK: ('file_size', 11) +@ CHECK: ('maxprot', 7) +@ CHECK: ('initprot', 7) +@ CHECK: ('num_sections', 2) +@ 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', 8) +@ CHECK: ('offset', 324) +@ CHECK: ('alignment', 2) +@ CHECK: ('reloc_offset', 336) +@ CHECK: ('num_reloc', 3) +@ CHECK: ('flags', 0x80000400) +@ CHECK: ('reserved1', 0) +@ CHECK: ('reserved2', 0) +@ CHECK: ), +@ CHECK: ('_relocations', [ +@ CHECK: # Relocation 0 +@ CHECK: (('word-0', 0xa2000004), +@ CHECK: ('word-1', 0x8)), +@ CHECK: # Relocation 1 +@ CHECK: (('word-0', 0xa1000000), +@ CHECK: ('word-1', 0x0)), +@ CHECK: # Relocation 2 +@ CHECK: (('word-0', 0x0), +@ CHECK-FIXME: ('word-1', 0x6d000001)), +@ CHECK: ]) +@ CHECK-FIXME: ('_section_data', 'fff7feef 04000000') +@ CHECK: # Section 1 +@ 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', 3) +@ CHECK: ('offset', 332) +@ CHECK: ('alignment', 2) +@ CHECK: ('reloc_offset', 0) +@ CHECK: ('num_reloc', 0) +@ CHECK: ('flags', 0x2) +@ CHECK: ('reserved1', 0) +@ CHECK: ('reserved2', 0) +@ CHECK: ), +@ CHECK: ('_relocations', [ +@ CHECK: ]) +@ CHECK: ('_section_data', '733000') +@ CHECK: ]) +@ CHECK: ), +@ CHECK: # Load Command 1 +@ CHECK: (('command', 2) +@ CHECK: ('size', 24) +@ CHECK: ('symoff', 360) +@ CHECK: ('nsyms', 2) +@ CHECK: ('stroff', 384) +@ CHECK: ('strsize', 16) +@ CHECK: ('_string_data', '\x00_main\x00_printf\x00\x00') +@ CHECK: ('_symbols', [ +@ CHECK: # Symbol 0 +@ CHECK: (('n_strx', 1) +@ CHECK: ('n_type', 0xf) +@ CHECK: ('n_sect', 1) +@ CHECK-FIXME: ('n_desc', 8) +@ CHECK: ('n_value', 0) +@ CHECK: ('_string', '_main') +@ CHECK: ), +@ CHECK: # Symbol 1 +@ CHECK: (('n_strx', 7) +@ 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', 0) +@ CHECK: ('iextdefsym', 0) +@ CHECK: ('nextdefsym', 1) +@ 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 clattner at apple.com Fri Dec 24 11:35:18 2010 From: clattner at apple.com (Chris Lattner) Date: Fri, 24 Dec 2010 09:35:18 -0800 Subject: [llvm-commits] [llvm] r122516 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp In-Reply-To: References: <20101223205735.3796C2A6C12C@llvm.org> Message-ID: <848BDD2A-4593-4ECA-84B0-6F7DB7617791@apple.com> On Dec 24, 2010, at 8:12 AM, Benjamin Kramer wrote: > > On 23.12.2010, at 21:57, Owen Anderson wrote: > >> Author: resistor >> Date: Thu Dec 23 14:57:35 2010 >> New Revision: 122516 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=122516&view=rev >> Log: >> It is possible for SimplifyCFG to cause PHI nodes to become redundant too late in the optimization >> pipeline to be caught by instcombine, and it's not feasible to catch them in SimplifyCFG because the >> use-lists are in an inconsistent state at the point where it could know that it need to simplify them. >> Instead, have CodeGenPrepare look for trivially redundant PHIs as part of its general cleanup effort. > > Would it hurt much if we ran SimplifyInstruction on all instructions, not just PHIs? I've seen SimplifyCFG > producing other nonsense like "%y = or i1 false, %x" too. There is a more general pass ordering issue here, see: http://llvm.org/bugs/show_bug.cgi?id=2338 For example. Perhaps the right answer is to just run a pass of instcombine at the end, to make sure things are fully canonicalized going into codegen. -Chris From benny.kra at googlemail.com Fri Dec 24 15:17:13 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Fri, 24 Dec 2010 21:17:13 -0000 Subject: [llvm-commits] [llvm] r122548 - in /llvm/trunk: lib/Transforms/Scalar/MemCpyOptimizer.cpp test/Transforms/MemCpyOpt/memcpy-to-memset.ll Message-ID: <20101224211713.2176C2A6C12C@llvm.org> Author: d0k Date: Fri Dec 24 15:17:12 2010 New Revision: 122548 URL: http://llvm.org/viewvc/llvm-project?rev=122548&view=rev Log: MemCpyOpt: Turn memcpys from a constant into a memset if possible. This allows us to compile "int cst[] = {-1, -1, -1};" into movl $-1, 16(%rsp) movq $-1, 8(%rsp) instead of movl _cst+8(%rip), %eax movl %eax, 16(%rsp) movq _cst(%rip), %rax movq %rax, 8(%rsp) Added: llvm/trunk/test/Transforms/MemCpyOpt/memcpy-to-memset.ll Modified: llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Modified: llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp?rev=122548&r1=122547&r2=122548&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Fri Dec 24 15:17:12 2010 @@ -14,6 +14,7 @@ #define DEBUG_TYPE "memcpyopt" #include "llvm/Transforms/Scalar.h" +#include "llvm/GlobalVariable.h" #include "llvm/IntrinsicInst.h" #include "llvm/Instructions.h" #include "llvm/ADT/SmallVector.h" @@ -31,6 +32,7 @@ STATISTIC(NumMemCpyInstr, "Number of memcpy instructions deleted"); STATISTIC(NumMemSetInfer, "Number of memsets inferred"); STATISTIC(NumMoveToCpy, "Number of memmoves converted to memcpy"); +STATISTIC(NumCpyToSet, "Number of memcpys converted to memset"); /// isBytewiseValue - If the specified value can be set by repeating the same /// byte in memory, return the i8 value that it is represented with. This is @@ -38,6 +40,13 @@ /// i16 0xF0F0, double 0.0 etc. If the value can't be handled with a repeated /// byte store (e.g. i16 0x1234), return null. static Value *isBytewiseValue(Value *V) { + // Look through constant globals. + if (GlobalVariable *GV = dyn_cast(V)) { + if (GV->mayBeOverridden() || !GV->isConstant() || !GV->hasInitializer()) + return 0; + V = GV->getInitializer(); + } + // All byte-wide stores are splatable, even of arbitrary variables. if (V->getType()->isIntegerTy(8)) return V; @@ -73,7 +82,24 @@ return ConstantInt::get(V->getContext(), Val); } } - + + // A ConstantArray is splatable if all its members are equal and also + // splatable. + if (ConstantArray *CA = dyn_cast(V)) { + if (CA->getNumOperands() == 0) + return 0; + + Value *Val = isBytewiseValue(CA->getOperand(0)); + if (!Val) + return 0; + + for (unsigned I = 1, E = CA->getNumOperands(); I != E; ++I) + if (CA->getOperand(I-1) != CA->getOperand(I)) + return 0; + + return Val; + } + // Conceptually, we could handle things like: // %a = zext i8 %X to i16 // %b = shl i16 %a, 8 @@ -765,8 +791,24 @@ M->eraseFromParent(); return false; } - - + + // If copying from a constant, try to turn the memcpy into a memset. + if (Value *ByteVal = isBytewiseValue(M->getSource())) { + Value *Ops[] = { + M->getRawDest(), ByteVal, // Start, value + CopySize, // Size + M->getAlignmentCst(), // Alignment + ConstantInt::getFalse(M->getContext()), // volatile + }; + const Type *Tys[] = { Ops[0]->getType(), Ops[2]->getType() }; + Module *Mod = M->getParent()->getParent()->getParent(); + Function *MemSetF = Intrinsic::getDeclaration(Mod, Intrinsic::memset, Tys, 2); + CallInst::Create(MemSetF, Ops, Ops+5, "", M); + M->eraseFromParent(); + ++NumCpyToSet; + return true; + } + // The are two possible optimizations we can do for memcpy: // a) memcpy-memcpy xform which exposes redundance for DSE. // b) call-memcpy xform for return slot optimization. Added: llvm/trunk/test/Transforms/MemCpyOpt/memcpy-to-memset.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/MemCpyOpt/memcpy-to-memset.ll?rev=122548&view=auto ============================================================================== --- llvm/trunk/test/Transforms/MemCpyOpt/memcpy-to-memset.ll (added) +++ llvm/trunk/test/Transforms/MemCpyOpt/memcpy-to-memset.ll Fri Dec 24 15:17:12 2010 @@ -0,0 +1,19 @@ +; RUN: opt -memcpyopt -S < %s | FileCheck %s + + at cst = internal constant [3 x i32] [i32 -1, i32 -1, i32 -1], align 4 + +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind +declare void @foo(i32*) nounwind + +define void @test1() nounwind { + %arr = alloca [3 x i32], align 4 + %arr_i8 = bitcast [3 x i32]* %arr to i8* + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %arr_i8, i8* bitcast ([3 x i32]* @cst to i8*), i64 12, i32 4, i1 false) + %arraydecay = getelementptr inbounds [3 x i32]* %arr, i64 0, i64 0 + call void @foo(i32* %arraydecay) nounwind + ret void +; CHECK: @test1 +; CHECK: call void @llvm.memset +; CHECK-NOT: call void @llvm.memcpy +; CHECK: ret void +} From rafael.espindola at gmail.com Fri Dec 24 15:22:02 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Fri, 24 Dec 2010 21:22:02 -0000 Subject: [llvm-commits] [llvm] r122549 - in /llvm/trunk: include/llvm/MC/MCObjectWriter.h lib/MC/ELFObjectWriter.cpp lib/MC/MCAssembler.cpp lib/MC/MCObjectWriter.cpp lib/MC/MachObjectWriter.cpp lib/MC/WinCOFFObjectWriter.cpp Message-ID: <20101224212203.03A732A6C12C@llvm.org> Author: rafael Date: Fri Dec 24 15:22:02 2010 New Revision: 122549 URL: http://llvm.org/viewvc/llvm-project?rev=122549&view=rev Log: Merge IsFixupFullyResolved and IsSymbolRefDifferenceFullyResolved. We now have a single point where targets test if a relocation is needed. Modified: llvm/trunk/include/llvm/MC/MCObjectWriter.h llvm/trunk/lib/MC/ELFObjectWriter.cpp llvm/trunk/lib/MC/MCAssembler.cpp llvm/trunk/lib/MC/MCObjectWriter.cpp llvm/trunk/lib/MC/MachObjectWriter.cpp llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp Modified: llvm/trunk/include/llvm/MC/MCObjectWriter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCObjectWriter.h?rev=122549&r1=122548&r2=122549&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCObjectWriter.h (original) +++ llvm/trunk/include/llvm/MC/MCObjectWriter.h Fri Dec 24 15:22:02 2010 @@ -21,6 +21,7 @@ class MCFixup; class MCFragment; class MCSymbol; +class MCSymbolData; class MCSymbolRefExpr; class MCValue; class raw_ostream; @@ -84,21 +85,19 @@ /// /// Clients are not required to answer precisely and may conservatively return /// false, even when a difference is fully resolved. - virtual bool + bool IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm, const MCSymbolRefExpr *A, const MCSymbolRefExpr *B, bool InSet) const; - /// Check if a fixup is fully resolved. - /// - /// This routine is used by the assembler to let the file format decide - /// if a fixup is not fully resolved. For example, one that crosses - /// two sections on ELF. - virtual bool IsFixupFullyResolved(const MCAssembler &Asm, - const MCValue Target, - bool IsPCRel, - const MCFragment *DF) const = 0; + virtual bool + IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, + const MCSymbolData &DataA, + const MCFragment &FB, + bool InSet, + bool IsPCRel) const = 0; + /// Write the object file. /// Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=122549&r1=122548&r2=122549&view=diff ============================================================================== --- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Fri Dec 24 15:22:02 2010 @@ -344,10 +344,12 @@ MCDataFragment *F, const MCSectionData *SD); - virtual bool IsFixupFullyResolved(const MCAssembler &Asm, - const MCValue Target, - bool IsPCRel, - const MCFragment *DF) const; + virtual bool + IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, + const MCSymbolData &DataA, + const MCFragment &FB, + bool InSet, + bool IsPCRel) const; virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout); virtual void WriteSection(MCAssembler &Asm, @@ -1154,50 +1156,22 @@ } } -bool ELFObjectWriter::IsFixupFullyResolved(const MCAssembler &Asm, - const MCValue Target, - bool IsPCRel, - const MCFragment *DF) const { - // If this is a PCrel relocation, find the section this fixup value is - // relative to. - const MCSection *BaseSection = 0; - if (IsPCRel) { - BaseSection = &DF->getParent()->getSection(); - assert(BaseSection); - } - - const MCSection *SectionA = 0; - const MCSymbol *SymbolA = 0; - if (const MCSymbolRefExpr *A = Target.getSymA()) { - SymbolA = &A->getSymbol(); - SectionA = &SymbolA->AliasedSymbol().getSection(); - } - - const MCSection *SectionB = 0; - const MCSymbol *SymbolB = 0; - if (const MCSymbolRefExpr *B = Target.getSymB()) { - SymbolB = &B->getSymbol(); - SectionB = &SymbolB->AliasedSymbol().getSection(); - } - - if (!BaseSection) - return SectionA == SectionB; - - if (SymbolB) - return false; - - // Absolute address but PCrel instruction, so we need a relocation. - if (!SymbolA) - return false; - +bool +ELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, + const MCSymbolData &DataA, + const MCFragment &FB, + bool InSet, + bool IsPCRel) const { // FIXME: This is in here just to match gnu as output. If the two ends // are in the same section, there is nothing that the linker can do to // break it. - const MCSymbolData &DataA = Asm.getSymbolData(*SymbolA); if (DataA.isExternal()) return false; - return BaseSection == SectionA; + const MCSection &SecA = DataA.getSymbol().AliasedSymbol().getSection(); + const MCSection &SecB = FB.getParent()->getSection(); + // On ELF A - B is absolute if A and B are in the same section. + return &SecA == &SecB; } void ELFObjectWriter::CreateGroupSections(MCAssembler &Asm, Modified: llvm/trunk/lib/MC/MCAssembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=122549&r1=122548&r2=122549&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCAssembler.cpp (original) +++ llvm/trunk/lib/MC/MCAssembler.cpp Fri Dec 24 15:22:02 2010 @@ -11,6 +11,7 @@ #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCSection.h" @@ -218,22 +219,37 @@ 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 - // doesn't support small relocations, but then under what criteria does the - // assembler allow symbol differences? + bool IsPCRel = Backend.getFixupKindInfo( + Fixup.getKind()).Flags & MCFixupKindInfo::FKF_IsPCRel; + + bool IsResolved; + if (IsPCRel) { + if (Target.getSymB()) { + IsResolved = false; + } else if (!Target.getSymA()) { + IsResolved = false; + } else { + const MCSymbol &SA = Target.getSymA()->getSymbol(); + if (SA.AliasedSymbol().isUndefined()) { + IsResolved = false; + } else { + const MCSymbolData &DataA = getSymbolData(SA); + IsResolved = + getWriter().IsSymbolRefDifferenceFullyResolvedImpl(*this, DataA, + *DF, false, true); + } + } + } else { + IsResolved = Target.isAbsolute(); + } Value = Target.getConstant(); - bool IsPCRel = Backend.getFixupKindInfo( - Fixup.getKind()).Flags & MCFixupKindInfo::FKF_IsPCRel; - bool IsResolved = true; bool IsThumb = false; if (const MCSymbolRefExpr *A = Target.getSymA()) { const MCSymbol &Sym = A->getSymbol().AliasedSymbol(); if (Sym.isDefined()) Value += Layout.getSymbolOffset(&getSymbolData(Sym)); - else - IsResolved = false; if (isThumbFunc(&Sym)) IsThumb = true; } @@ -241,12 +257,8 @@ const MCSymbol &Sym = B->getSymbol().AliasedSymbol(); if (Sym.isDefined()) Value -= Layout.getSymbolOffset(&getSymbolData(Sym)); - else - IsResolved = false; } - if (IsResolved) - IsResolved = getWriter().IsFixupFullyResolved(*this, Target, IsPCRel, DF); bool ShouldAlignPC = Backend.getFixupKindInfo(Fixup.getKind()).Flags & MCFixupKindInfo::FKF_IsAlignedDownTo32Bits; Modified: llvm/trunk/lib/MC/MCObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCObjectWriter.cpp?rev=122549&r1=122548&r2=122549&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/MCObjectWriter.cpp Fri Dec 24 15:22:02 2010 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCSymbol.h" @@ -54,9 +55,14 @@ const MCSymbol &SA = A->getSymbol(); const MCSymbol &SB = B->getSymbol(); - if (SA.isUndefined() || SB.isUndefined()) + if (SA.AliasedSymbol().isUndefined() || SB.AliasedSymbol().isUndefined()) return false; - // On ELF and COFF A - B is absolute if A and B are in the same section. - return &SA.getSection() == &SB.getSection(); + const MCSymbolData &DataA = Asm.getSymbolData(SA); + const MCSymbolData &DataB = Asm.getSymbolData(SB); + + return IsSymbolRefDifferenceFullyResolvedImpl(Asm, DataA, + *DataB.getFragment(), + InSet, + false); } Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=122549&r1=122548&r2=122549&view=diff ============================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/MachObjectWriter.cpp Fri Dec 24 15:22:02 2010 @@ -64,86 +64,6 @@ return false; } -static bool isScatteredFixupFullyResolved(const MCAssembler &Asm, - const MCValue Target, - const MCSymbolData *BaseSymbol) { - // The effective fixup address is - // addr(atom(A)) + offset(A) - // - addr(atom(B)) - offset(B) - // - addr(BaseSymbol) + - // and the offsets are not relocatable, so the fixup is fully resolved when - // addr(atom(A)) - addr(atom(B)) - addr(BaseSymbol) == 0. - // - // Note that "false" is almost always conservatively correct (it means we emit - // a relocation which is unnecessary), except when it would force us to emit a - // relocation which the target cannot encode. - - const MCSymbolData *A_Base = 0, *B_Base = 0; - if (const MCSymbolRefExpr *A = Target.getSymA()) { - // Modified symbol references cannot be resolved. - if (A->getKind() != MCSymbolRefExpr::VK_None) - return false; - - A_Base = Asm.getAtom(&Asm.getSymbolData(A->getSymbol())); - if (!A_Base) - return false; - } - - if (const MCSymbolRefExpr *B = Target.getSymB()) { - // Modified symbol references cannot be resolved. - if (B->getKind() != MCSymbolRefExpr::VK_None) - return false; - - B_Base = Asm.getAtom(&Asm.getSymbolData(B->getSymbol())); - if (!B_Base) - return false; - } - - // If there is no base, A and B have to be the same atom for this fixup to be - // fully resolved. - if (!BaseSymbol) - return A_Base == B_Base; - - // Otherwise, B must be missing and A must be the base. - return !B_Base && BaseSymbol == A_Base; -} - -static bool isScatteredFixupFullyResolvedSimple(const MCAssembler &Asm, - const MCValue Target, - const MCSection *BaseSection) { - // The effective fixup address is - // addr(atom(A)) + offset(A) - // - addr(atom(B)) - offset(B) - // - addr() + - // and the offsets are not relocatable, so the fixup is fully resolved when - // addr(atom(A)) - addr(atom(B)) - addr()) == 0. - // - // The simple (Darwin, except on x86_64) way of dealing with this was to - // assume that any reference to a temporary symbol *must* be a temporary - // symbol in the same atom, unless the sections differ. Therefore, any PCrel - // relocation to a temporary symbol (in the same section) is fully - // resolved. This also works in conjunction with absolutized .set, which - // requires the compiler to use .set to absolutize the differences between - // symbols which the compiler knows to be assembly time constants, so we don't - // need to worry about considering symbol differences fully resolved. - - // Non-relative fixups are only resolved if constant. - if (!BaseSection) - return Target.isAbsolute(); - - // Otherwise, relative fixups are only resolved if not a difference and the - // target is a temporary in the same section. - if (Target.isAbsolute() || Target.getSymB()) - return false; - - const MCSymbol *A = &Target.getSymA()->getSymbol(); - if (!A->isTemporary() || !A->isInSection() || - &A->getSection() != BaseSection) - return false; - - return true; -} - namespace { class MachObjectWriter : public MCObjectWriter { @@ -1325,16 +1245,14 @@ UndefinedSymbolData); } - bool IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm, - const MCSymbolRefExpr *A, - const MCSymbolRefExpr *B, - bool InSet) const { + virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, + const MCSymbolData &DataA, + const MCFragment &FB, + bool InSet, + bool IsPCRel) const { if (InSet) return true; - if (!TargetObjectWriter->useAggressiveSymbolFolding()) - return false; - // The effective address is // addr(atom(A)) + offset(A) // - addr(atom(B)) - offset(B) @@ -1342,16 +1260,38 @@ // addr(atom(A)) - addr(atom(B)) == 0. const MCSymbolData *A_Base = 0, *B_Base = 0; - // Modified symbol references cannot be resolved. - if (A->getKind() != MCSymbolRefExpr::VK_None || - B->getKind() != MCSymbolRefExpr::VK_None) - return false; + const MCSymbol &SA = DataA.getSymbol().AliasedSymbol(); + const MCSection &SecA = SA.getSection(); + const MCSection &SecB = FB.getParent()->getSection(); + + if (IsPCRel) { + // The simple (Darwin, except on x86_64) way of dealing with this was to + // assume that any reference to a temporary symbol *must* be a temporary + // symbol in the same atom, unless the sections differ. Therefore, any + // PCrel relocation to a temporary symbol (in the same section) is fully + // resolved. This also works in conjunction with absolutized .set, which + // requires the compiler to use .set to absolutize the differences between + // symbols which the compiler knows to be assembly time constants, so we + // don't need to worry about considering symbol differences fully + // resolved. + + if (!Asm.getBackend().hasReliableSymbolDifference()) { + if (!SA.isTemporary() || !SA.isInSection() || &SecA != &SecB) + return false; + return true; + } + } else { + if (!TargetObjectWriter->useAggressiveSymbolFolding()) + return false; + } + + const MCFragment &FA = *Asm.getSymbolData(SA).getFragment(); - A_Base = Asm.getAtom(&Asm.getSymbolData(A->getSymbol())); + A_Base = FA.getAtom(); if (!A_Base) return false; - B_Base = Asm.getAtom(&Asm.getSymbolData(B->getSymbol())); + B_Base = FB.getAtom(); if (!B_Base) return false; @@ -1363,37 +1303,6 @@ return false; } - bool IsFixupFullyResolved(const MCAssembler &Asm, - const MCValue Target, - bool IsPCRel, - const MCFragment *DF) const { - // Otherwise, determine whether this value is actually resolved; scattering - // may cause atoms to move. - - // Check if we are using the "simple" resolution algorithm (e.g., - // i386). - if (!Asm.getBackend().hasReliableSymbolDifference()) { - const MCSection *BaseSection = 0; - if (IsPCRel) - BaseSection = &DF->getParent()->getSection(); - - return isScatteredFixupFullyResolvedSimple(Asm, Target, BaseSection); - } - - // Otherwise, compute the proper answer as reliably as possible. - - // If this is a PCrel relocation, find the base atom (identified by its - // symbol) that the fixup value is relative to. - const MCSymbolData *BaseSymbol = 0; - if (IsPCRel) { - BaseSymbol = DF->getAtom(); - if (!BaseSymbol) - return false; - } - - return isScatteredFixupFullyResolved(Asm, Target, BaseSymbol); - } - void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) { unsigned NumSections = Asm.size(); Modified: llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp?rev=122549&r1=122548&r2=122549&view=diff ============================================================================== --- llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp Fri Dec 24 15:22:02 2010 @@ -179,10 +179,12 @@ MCValue Target, uint64_t &FixedValue); - virtual bool IsFixupFullyResolved(const MCAssembler &Asm, - const MCValue Target, - bool IsPCRel, - const MCFragment *DF) const; + virtual bool + IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, + const MCSymbolData &DataA, + const MCFragment &FB, + bool InSet, + bool IsPCRel) const; void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout); }; @@ -717,34 +719,17 @@ coff_section->Relocations.push_back(Reloc); } -bool WinCOFFObjectWriter::IsFixupFullyResolved(const MCAssembler &Asm, - const MCValue Target, - bool IsPCRel, - const MCFragment *DF) const { - // If this is a PCrel relocation, find the section this fixup value is - // relative to. - const MCSection *BaseSection = 0; - if (IsPCRel) { - BaseSection = &DF->getParent()->getSection(); - assert(BaseSection); - } - - const MCSection *SectionA = 0; - const MCSymbol *SymbolA = 0; - if (const MCSymbolRefExpr *A = Target.getSymA()) { - SymbolA = &A->getSymbol(); - SectionA = &SymbolA->getSection(); - } - - const MCSection *SectionB = 0; - if (const MCSymbolRefExpr *B = Target.getSymB()) { - SectionB = &B->getSymbol().getSection(); - } - - if (!BaseSection) - return SectionA == SectionB; - - return !SectionB && BaseSection == SectionA; +bool +WinCOFFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( + const MCAssembler &Asm, + const MCSymbolData &DataA, + const MCFragment &FB, + bool InSet, + bool IsPCRel) const { + const MCSection &SecA = DataA.getSymbol().AliasedSymbol().getSection(); + const MCSection &SecB = FB.getParent()->getSection(); + // On COFF A - B is absolute if A and B are in the same section. + return &SecA == &SecB; } void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, From fvbommel at gmail.com Fri Dec 24 15:43:22 2010 From: fvbommel at gmail.com (Frits van Bommel) Date: Fri, 24 Dec 2010 22:43:22 +0100 Subject: [llvm-commits] [llvm] r122548 - in /llvm/trunk: lib/Transforms/Scalar/MemCpyOptimizer.cpp test/Transforms/MemCpyOpt/memcpy-to-memset.ll In-Reply-To: <20101224211713.2176C2A6C12C@llvm.org> References: <20101224211713.2176C2A6C12C@llvm.org> Message-ID: On Fri, Dec 24, 2010 at 10:17 PM, Benjamin Kramer wrote: > ?/// isBytewiseValue - If the specified value can be set by repeating the same > ?/// byte in memory, return the i8 value that it is represented with. ?This is > @@ -38,6 +40,13 @@ > ?/// i16 0xF0F0, double 0.0 etc. ?If the value can't be handled with a repeated > ?/// byte store (e.g. i16 0x1234), return null. > ?static Value *isBytewiseValue(Value *V) { > + ?// Look through constant globals. > + ?if (GlobalVariable *GV = dyn_cast(V)) { > + ? ?if (GV->mayBeOverridden() || !GV->isConstant() || !GV->hasInitializer()) > + ? ? ?return 0; > + ? ?V = GV->getInitializer(); > + ?} > + This shouldn't be done here. Putting this here can cause miscompilation when a pointer to a global is stored somewhere (by memset'ing the bytewise value of the *initializer* instead). This should probably be put into a separate function (e.g. isPointerToBytewiseValue()) that returns isBytewiseValue(GV->getInitializer()) if the conditions hold. > + ?// A ConstantArray is splatable if all its members are equal and also > + ?// splatable. > + ?if (ConstantArray *CA = dyn_cast(V)) { I notice this function doesn't seem to handle null values. There should probably be an if (V->isNullValue()) return Zero; or similar near here. Possibly even the same for undefs. (Currently it doesn't handle all-zero arrays & structs, for instance) > + ?// If copying from a constant, try to turn the memcpy into a memset. > + ?if (Value *ByteVal = isBytewiseValue(M->getSource())) { This should use the above-mentioned isPointerToBytewiseValue(...). > + ? ?Value *Ops[] = { > + ? ? ?M->getRawDest(), ByteVal, ? ? ? ? ? ? ? // Start, value > + ? ? ?CopySize, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // Size > + ? ? ?M->getAlignmentCst(), ? ? ? ? ? ? ? ? ? // Alignment > + ? ? ?ConstantInt::getFalse(M->getContext()), // volatile > + ? ?}; > + ? ?const Type *Tys[] = { Ops[0]->getType(), Ops[2]->getType() }; > + ? ?Module *Mod = M->getParent()->getParent()->getParent(); > + ? ?Function *MemSetF = Intrinsic::getDeclaration(Mod, Intrinsic::memset, Tys, 2); > + ? ?CallInst::Create(MemSetF, Ops, Ops+5, "", M); This can probably be simplified by using EmitMemSet() from llvm/Transforms/Utils/BuildLibCalls.h, but the same goes for the previously existing code in this file. From benny.kra at googlemail.com Fri Dec 24 16:23:59 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Fri, 24 Dec 2010 22:23:59 -0000 Subject: [llvm-commits] [llvm] r122550 - /llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Message-ID: <20101224222359.F03B12A6C12C@llvm.org> Author: d0k Date: Fri Dec 24 16:23:59 2010 New Revision: 122550 URL: http://llvm.org/viewvc/llvm-project?rev=122550&view=rev Log: Fix a thinko pointed out by Frits van Bommel: looking through global variables in isBytewiseValue is not safe. Modified: llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Modified: llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp?rev=122550&r1=122549&r2=122550&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Fri Dec 24 16:23:59 2010 @@ -40,13 +40,6 @@ /// i16 0xF0F0, double 0.0 etc. If the value can't be handled with a repeated /// byte store (e.g. i16 0x1234), return null. static Value *isBytewiseValue(Value *V) { - // Look through constant globals. - if (GlobalVariable *GV = dyn_cast(V)) { - if (GV->mayBeOverridden() || !GV->isConstant() || !GV->hasInitializer()) - return 0; - V = GV->getInitializer(); - } - // All byte-wide stores are splatable, even of arbitrary variables. if (V->getType()->isIntegerTy(8)) return V; @@ -793,21 +786,25 @@ } // If copying from a constant, try to turn the memcpy into a memset. - if (Value *ByteVal = isBytewiseValue(M->getSource())) { - Value *Ops[] = { - M->getRawDest(), ByteVal, // Start, value - CopySize, // Size - M->getAlignmentCst(), // Alignment - ConstantInt::getFalse(M->getContext()), // volatile - }; - const Type *Tys[] = { Ops[0]->getType(), Ops[2]->getType() }; - Module *Mod = M->getParent()->getParent()->getParent(); - Function *MemSetF = Intrinsic::getDeclaration(Mod, Intrinsic::memset, Tys, 2); - CallInst::Create(MemSetF, Ops, Ops+5, "", M); - M->eraseFromParent(); - ++NumCpyToSet; - return true; - } + if (GlobalVariable *GV = dyn_cast(M->getSource())) + if (!GV->mayBeOverridden() && GV->isConstant() && GV->hasInitializer()) + if (Value *ByteVal = isBytewiseValue(GV->getInitializer())) { + Value *Ops[] = { + M->getRawDest(), ByteVal, // Start, value + CopySize, // Size + M->getAlignmentCst(), // Alignment + ConstantInt::getFalse(M->getContext()), // volatile + }; + const Type *Tys[] = { Ops[0]->getType(), Ops[2]->getType() }; + Module *Mod = M->getParent()->getParent()->getParent(); + Function *MemSetF = Intrinsic::getDeclaration(Mod, Intrinsic::memset, + Tys, 2); + CallInst::Create(MemSetF, Ops, Ops+5, "", M); + MD->removeInstruction(M); + M->eraseFromParent(); + ++NumCpyToSet; + return true; + } // The are two possible optimizations we can do for memcpy: // a) memcpy-memcpy xform which exposes redundance for DSE. From benny.kra at googlemail.com Fri Dec 24 16:43:02 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Fri, 24 Dec 2010 23:43:02 +0100 Subject: [llvm-commits] [llvm] r122548 - in /llvm/trunk: lib/Transforms/Scalar/MemCpyOptimizer.cpp test/Transforms/MemCpyOpt/memcpy-to-memset.ll In-Reply-To: References: <20101224211713.2176C2A6C12C@llvm.org> Message-ID: On 24.12.2010, at 22:43, Frits van Bommel wrote: > On Fri, Dec 24, 2010 at 10:17 PM, Benjamin Kramer > wrote: >> /// isBytewiseValue - If the specified value can be set by repeating the same >> /// byte in memory, return the i8 value that it is represented with. This is >> @@ -38,6 +40,13 @@ >> /// i16 0xF0F0, double 0.0 etc. If the value can't be handled with a repeated >> /// byte store (e.g. i16 0x1234), return null. >> static Value *isBytewiseValue(Value *V) { >> + // Look through constant globals. >> + if (GlobalVariable *GV = dyn_cast(V)) { >> + if (GV->mayBeOverridden() || !GV->isConstant() || !GV->hasInitializer()) >> + return 0; >> + V = GV->getInitializer(); >> + } >> + > > This shouldn't be done here. Putting this here can cause > miscompilation when a pointer to a global is stored somewhere (by > memset'ing the bytewise value of the *initializer* instead). > This should probably be put into a separate function (e.g. > isPointerToBytewiseValue()) that returns > isBytewiseValue(GV->getInitializer()) if the conditions hold. Fixed, thanks for pointing that out *smacks forehead* > >> + // A ConstantArray is splatable if all its members are equal and also >> + // splatable. >> + if (ConstantArray *CA = dyn_cast(V)) { > > I notice this function doesn't seem to handle null values. There > should probably be an > if (V->isNullValue()) return Zero; > or similar near here. > Possibly even the same for undefs. > (Currently it doesn't handle all-zero arrays & structs, for instance) It should handle all-zero arrays just fine. memcpy/memset/store from undef shouldn't make it this far. > >> + // If copying from a constant, try to turn the memcpy into a memset. >> + if (Value *ByteVal = isBytewiseValue(M->getSource())) { > > This should use the above-mentioned isPointerToBytewiseValue(...). > >> + Value *Ops[] = { >> + M->getRawDest(), ByteVal, // Start, value >> + CopySize, // Size >> + M->getAlignmentCst(), // Alignment >> + ConstantInt::getFalse(M->getContext()), // volatile >> + }; >> + const Type *Tys[] = { Ops[0]->getType(), Ops[2]->getType() }; >> + Module *Mod = M->getParent()->getParent()->getParent(); >> + Function *MemSetF = Intrinsic::getDeclaration(Mod, Intrinsic::memset, Tys, 2); >> + CallInst::Create(MemSetF, Ops, Ops+5, "", M); > > This can probably be simplified by using EmitMemSet() from > llvm/Transforms/Utils/BuildLibCalls.h, but the same goes for the > previously existing code in this file. Agreed, the interface needs some massaging though, currently it completely ignores alignment, requires but doesn't use TargetData etc. From echristo at apple.com Fri Dec 24 20:38:01 2010 From: echristo at apple.com (Eric Christopher) Date: Sat, 25 Dec 2010 02:38:01 -0000 Subject: [llvm-commits] [llvm] r122551 - /llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Message-ID: <20101225023801.3A7562A6C12C@llvm.org> Author: echristo Date: Fri Dec 24 20:38:01 2010 New Revision: 122551 URL: http://llvm.org/viewvc/llvm-project?rev=122551&view=rev Log: Header warning patrol. Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=122551&r1=122550&r2=122551&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Fri Dec 24 20:38:01 2010 @@ -442,7 +442,7 @@ bool hasReadyFilter() const { return HasReadyFilter; } - virtual bool isReady(SUnit *U) const { + virtual bool isReady(SUnit *) const { assert(!HasReadyFilter && "The ready filter must override isReady()"); return true; } @@ -458,7 +458,7 @@ virtual void remove(SUnit *SU) = 0; - virtual void dump(ScheduleDAG *DAG) const {} + virtual void dump(ScheduleDAG *) const {} /// ScheduledNode - As each node is scheduled, this method is invoked. This /// allows the priority function to adjust the priority of related From bigcheesegs at gmail.com Sat Dec 25 14:10:11 2010 From: bigcheesegs at gmail.com (Michael J. Spencer) Date: Sat, 25 Dec 2010 20:10:11 -0000 Subject: [llvm-commits] [llvm] r122553 - in /llvm/trunk: include/llvm/Support/PathV1.h lib/Support/Unix/Path.inc Message-ID: <20101225201011.EF20F2A6C12C@llvm.org> Author: mspencer Date: Sat Dec 25 14:10:11 2010 New Revision: 122553 URL: http://llvm.org/viewvc/llvm-project?rev=122553&view=rev Log: Support/PathV1: Deprecate makeAbsolute and remove Unix impl because it annoys people. Modified: llvm/trunk/include/llvm/Support/PathV1.h llvm/trunk/lib/Support/Unix/Path.inc Modified: llvm/trunk/include/llvm/Support/PathV1.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/PathV1.h?rev=122553&r1=122552&r2=122553&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/PathV1.h (original) +++ llvm/trunk/include/llvm/Support/PathV1.h Sat Dec 25 14:10:11 2010 @@ -494,7 +494,9 @@ /// The current Path name is made absolute by prepending the /// current working directory if necessary. - void makeAbsolute(); + LLVM_ATTRIBUTE_DEPRECATED( + void makeAbsolute(), + LLVMV_PATH_DEPRECATED_MSG(fs::make_absolute)); /// @} /// @name Disk Mutators Modified: llvm/trunk/lib/Support/Unix/Path.inc URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/Path.inc?rev=122553&r1=122552&r2=122553&view=diff ============================================================================== --- llvm/trunk/lib/Support/Unix/Path.inc (original) +++ llvm/trunk/lib/Support/Unix/Path.inc Sat Dec 25 14:10:11 2010 @@ -119,18 +119,6 @@ return path[0] == '/'; } -void Path::makeAbsolute() { - if (isAbsolute()) - return; - - Path CWD = Path::GetCurrentDirectory(); - assert(CWD.isAbsolute() && "GetCurrentDirectory returned relative path!"); - - CWD.appendComponent(path); - - path = CWD.str(); -} - Path Path::GetRootDirectory() { Path result; From sabre at nondot.org Sat Dec 25 14:37:57 2010 From: sabre at nondot.org (Chris Lattner) Date: Sat, 25 Dec 2010 20:37:57 -0000 Subject: [llvm-commits] [llvm] r122554 - in /llvm/trunk: include/llvm/Transforms/Utils/Local.h lib/Transforms/InstCombine/InstCombine.h lib/Transforms/InstCombine/InstCombineCalls.cpp lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp lib/Transforms/Utils/Local.cpp Message-ID: <20101225203757.E89B12A6C12C@llvm.org> Author: lattner Date: Sat Dec 25 14:37:57 2010 New Revision: 122554 URL: http://llvm.org/viewvc/llvm-project?rev=122554&view=rev Log: Move getOrEnforceKnownAlignment out of instcombine into Transforms/Utils. Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h llvm/trunk/lib/Transforms/InstCombine/InstCombine.h llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp llvm/trunk/lib/Transforms/Utils/Local.cpp Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Local.h?rev=122554&r1=122553&r2=122554&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/Local.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/Local.h Sat Dec 25 14:37:57 2010 @@ -145,6 +145,18 @@ /// The phi node is deleted and it returns the pointer to the alloca inserted. AllocaInst *DemotePHIToStack(PHINode *P, Instruction *AllocaPoint = 0); +/// getOrEnforceKnownAlignment - If the specified pointer has an alignment that +/// we can determine, return it, otherwise return 0. If PrefAlign is specified, +/// and it is more than the alignment of the ultimate object, see if we can +/// increase the alignment of the ultimate object, making this check succeed. +unsigned getOrEnforceKnownAlignment(Value *V, unsigned PrefAlign, + const TargetData *TD = 0); + +/// getKnownAlignment - Try to infer an alignment for the specified pointer. +static inline unsigned getKnownAlignment(Value *V, const TargetData *TD = 0) { + return getOrEnforceKnownAlignment(V, 0, TD); +} + } // End llvm namespace #endif Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombine.h?rev=122554&r1=122553&r2=122554&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombine.h (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombine.h Sat Dec 25 14:37:57 2010 @@ -348,10 +348,6 @@ Value *EvaluateInDifferentType(Value *V, const Type *Ty, bool isSigned); - - unsigned GetOrEnforceKnownAlignment(Value *V, - unsigned PrefAlign = 0); - }; Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=122554&r1=122553&r2=122554&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Sat Dec 25 14:37:57 2010 @@ -17,6 +17,7 @@ #include "llvm/Target/TargetData.h" #include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Transforms/Utils/BuildLibCalls.h" +#include "llvm/Transforms/Utils/Local.h" using namespace llvm; /// getPromotedType - Return the specified type promoted as it would be to pass @@ -29,100 +30,10 @@ return Ty; } -/// EnforceKnownAlignment - If the specified pointer points to an object that -/// we control, modify the object's alignment to PrefAlign. This isn't -/// often possible though. If alignment is important, a more reliable approach -/// is to simply align all global variables and allocation instructions to -/// their preferred alignment from the beginning. -/// -static unsigned EnforceKnownAlignment(Value *V, - unsigned Align, unsigned PrefAlign) { - - User *U = dyn_cast(V); - if (!U) return Align; - - switch (Operator::getOpcode(U)) { - default: break; - case Instruction::BitCast: - return EnforceKnownAlignment(U->getOperand(0), Align, PrefAlign); - case Instruction::GetElementPtr: { - // If all indexes are zero, it is just the alignment of the base pointer. - bool AllZeroOperands = true; - for (User::op_iterator i = U->op_begin() + 1, e = U->op_end(); i != e; ++i) - if (!isa(*i) || - !cast(*i)->isNullValue()) { - AllZeroOperands = false; - break; - } - - if (AllZeroOperands) { - // Treat this like a bitcast. - return EnforceKnownAlignment(U->getOperand(0), Align, PrefAlign); - } - return Align; - } - case Instruction::Alloca: { - AllocaInst *AI = cast(V); - // If there is a requested alignment and if this is an alloca, round up. - if (AI->getAlignment() >= PrefAlign) - return AI->getAlignment(); - AI->setAlignment(PrefAlign); - return PrefAlign; - } - } - - if (GlobalValue *GV = dyn_cast(V)) { - // If there is a large requested alignment and we can, bump up the alignment - // of the global. - if (GV->isDeclaration()) return Align; - - if (GV->getAlignment() >= PrefAlign) - return GV->getAlignment(); - // We can only increase the alignment of the global if it has no alignment - // specified or if it is not assigned a section. If it is assigned a - // section, the global could be densely packed with other objects in the - // section, increasing the alignment could cause padding issues. - if (!GV->hasSection() || GV->getAlignment() == 0) - GV->setAlignment(PrefAlign); - return GV->getAlignment(); - } - - return Align; -} - -/// GetOrEnforceKnownAlignment - If the specified pointer has an alignment that -/// we can determine, return it, otherwise return 0. If PrefAlign is specified, -/// and it is more than the alignment of the ultimate object, see if we can -/// increase the alignment of the ultimate object, making this check succeed. -unsigned InstCombiner::GetOrEnforceKnownAlignment(Value *V, - unsigned PrefAlign) { - assert(V->getType()->isPointerTy() && - "GetOrEnforceKnownAlignment expects a pointer!"); - unsigned BitWidth = TD ? TD->getPointerSizeInBits() : 64; - APInt Mask = APInt::getAllOnesValue(BitWidth); - APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0); - ComputeMaskedBits(V, Mask, KnownZero, KnownOne); - unsigned TrailZ = KnownZero.countTrailingOnes(); - - // Avoid trouble with rediculously large TrailZ values, such as - // those computed from a null pointer. - TrailZ = std::min(TrailZ, unsigned(sizeof(unsigned) * CHAR_BIT - 1)); - - unsigned Align = 1u << std::min(BitWidth - 1, TrailZ); - - // LLVM doesn't support alignments larger than this currently. - Align = std::min(Align, +Value::MaximumAlignment); - - if (PrefAlign > Align) - Align = EnforceKnownAlignment(V, Align, PrefAlign); - - // We don't need to make any adjustment. - return Align; -} Instruction *InstCombiner::SimplifyMemTransfer(MemIntrinsic *MI) { - unsigned DstAlign = GetOrEnforceKnownAlignment(MI->getArgOperand(0)); - unsigned SrcAlign = GetOrEnforceKnownAlignment(MI->getArgOperand(1)); + unsigned DstAlign = getKnownAlignment(MI->getArgOperand(0), TD); + unsigned SrcAlign = getKnownAlignment(MI->getArgOperand(1), TD); unsigned MinAlign = std::min(DstAlign, SrcAlign); unsigned CopyAlign = MI->getAlignment(); @@ -211,7 +122,7 @@ } Instruction *InstCombiner::SimplifyMemSet(MemSetInst *MI) { - unsigned Alignment = GetOrEnforceKnownAlignment(MI->getDest()); + unsigned Alignment = getKnownAlignment(MI->getDest()); if (MI->getAlignment() < Alignment) { MI->setAlignment(ConstantInt::get(MI->getAlignmentType(), Alignment, false)); @@ -611,7 +522,7 @@ case Intrinsic::x86_sse2_loadu_dq: // Turn PPC lvx -> load if the pointer is known aligned. // Turn X86 loadups -> load if the pointer is known aligned. - if (GetOrEnforceKnownAlignment(II->getArgOperand(0), 16) >= 16) { + if (getOrEnforceKnownAlignment(II->getArgOperand(0), 16, TD) >= 16) { Value *Ptr = Builder->CreateBitCast(II->getArgOperand(0), PointerType::getUnqual(II->getType())); return new LoadInst(Ptr); @@ -620,7 +531,7 @@ case Intrinsic::ppc_altivec_stvx: case Intrinsic::ppc_altivec_stvxl: // Turn stvx -> store if the pointer is known aligned. - if (GetOrEnforceKnownAlignment(II->getArgOperand(1), 16) >= 16) { + if (getOrEnforceKnownAlignment(II->getArgOperand(1), 16, TD) >= 16) { const Type *OpPtrTy = PointerType::getUnqual(II->getArgOperand(0)->getType()); Value *Ptr = Builder->CreateBitCast(II->getArgOperand(1), OpPtrTy); @@ -631,7 +542,7 @@ case Intrinsic::x86_sse2_storeu_pd: case Intrinsic::x86_sse2_storeu_dq: // Turn X86 storeu -> store if the pointer is known aligned. - if (GetOrEnforceKnownAlignment(II->getArgOperand(0), 16) >= 16) { + if (getOrEnforceKnownAlignment(II->getArgOperand(0), 16, TD) >= 16) { const Type *OpPtrTy = PointerType::getUnqual(II->getArgOperand(1)->getType()); Value *Ptr = Builder->CreateBitCast(II->getArgOperand(0), OpPtrTy); @@ -718,7 +629,7 @@ case Intrinsic::arm_neon_vst2lane: case Intrinsic::arm_neon_vst3lane: case Intrinsic::arm_neon_vst4lane: { - unsigned MemAlign = GetOrEnforceKnownAlignment(II->getArgOperand(0)); + unsigned MemAlign = getKnownAlignment(II->getArgOperand(0)); unsigned AlignArg = II->getNumArgOperands() - 1; ConstantInt *IntrAlign = dyn_cast(II->getArgOperand(AlignArg)); if (IntrAlign && IntrAlign->getZExtValue() < MemAlign) { Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp?rev=122554&r1=122553&r2=122554&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp Sat Dec 25 14:37:57 2010 @@ -145,7 +145,7 @@ // Attempt to improve the alignment. if (TD) { unsigned KnownAlign = - GetOrEnforceKnownAlignment(Op, TD->getPrefTypeAlignment(LI.getType())); + getOrEnforceKnownAlignment(Op, TD->getPrefTypeAlignment(LI.getType()),TD); unsigned LoadAlign = LI.getAlignment(); unsigned EffectiveLoadAlign = LoadAlign != 0 ? LoadAlign : TD->getABITypeAlignment(LI.getType()); @@ -416,7 +416,8 @@ // Attempt to improve the alignment. if (TD) { unsigned KnownAlign = - GetOrEnforceKnownAlignment(Ptr, TD->getPrefTypeAlignment(Val->getType())); + getOrEnforceKnownAlignment(Ptr, TD->getPrefTypeAlignment(Val->getType()), + TD); unsigned StoreAlign = SI.getAlignment(); unsigned EffectiveStoreAlign = StoreAlign != 0 ? StoreAlign : TD->getABITypeAlignment(Val->getType()); Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=122554&r1=122553&r2=122554&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Sat Dec 25 14:37:57 2010 @@ -25,6 +25,7 @@ #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/ProfileInfo.h" +#include "llvm/Analysis/ValueTracking.h" #include "llvm/Target/TargetData.h" #include "llvm/Support/CFG.h" #include "llvm/Support/Debug.h" @@ -642,3 +643,94 @@ return Changed; } + +/// enforceKnownAlignment - If the specified pointer points to an object that +/// we control, modify the object's alignment to PrefAlign. This isn't +/// often possible though. If alignment is important, a more reliable approach +/// is to simply align all global variables and allocation instructions to +/// their preferred alignment from the beginning. +/// +unsigned enforceKnownAlignment(Value *V, unsigned Align, unsigned PrefAlign) { + + User *U = dyn_cast(V); + if (!U) return Align; + + switch (Operator::getOpcode(U)) { + default: break; + case Instruction::BitCast: + return enforceKnownAlignment(U->getOperand(0), Align, PrefAlign); + case Instruction::GetElementPtr: { + // If all indexes are zero, it is just the alignment of the base pointer. + bool AllZeroOperands = true; + for (User::op_iterator i = U->op_begin() + 1, e = U->op_end(); i != e; ++i) + if (!isa(*i) || + !cast(*i)->isNullValue()) { + AllZeroOperands = false; + break; + } + + if (AllZeroOperands) { + // Treat this like a bitcast. + return enforceKnownAlignment(U->getOperand(0), Align, PrefAlign); + } + return Align; + } + case Instruction::Alloca: { + AllocaInst *AI = cast(V); + // If there is a requested alignment and if this is an alloca, round up. + if (AI->getAlignment() >= PrefAlign) + return AI->getAlignment(); + AI->setAlignment(PrefAlign); + return PrefAlign; + } + } + + if (GlobalValue *GV = dyn_cast(V)) { + // If there is a large requested alignment and we can, bump up the alignment + // of the global. + if (GV->isDeclaration()) return Align; + + if (GV->getAlignment() >= PrefAlign) + return GV->getAlignment(); + // We can only increase the alignment of the global if it has no alignment + // specified or if it is not assigned a section. If it is assigned a + // section, the global could be densely packed with other objects in the + // section, increasing the alignment could cause padding issues. + if (!GV->hasSection() || GV->getAlignment() == 0) + GV->setAlignment(PrefAlign); + return GV->getAlignment(); + } + + return Align; +} + +/// getOrEnforceKnownAlignment - If the specified pointer has an alignment that +/// we can determine, return it, otherwise return 0. If PrefAlign is specified, +/// and it is more than the alignment of the ultimate object, see if we can +/// increase the alignment of the ultimate object, making this check succeed. +unsigned llvm::getOrEnforceKnownAlignment(Value *V, unsigned PrefAlign, + const TargetData *TD) { + assert(V->getType()->isPointerTy() && + "getOrEnforceKnownAlignment expects a pointer!"); + unsigned BitWidth = TD ? TD->getPointerSizeInBits() : 64; + APInt Mask = APInt::getAllOnesValue(BitWidth); + APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0); + ComputeMaskedBits(V, Mask, KnownZero, KnownOne); + unsigned TrailZ = KnownZero.countTrailingOnes(); + + // Avoid trouble with rediculously large TrailZ values, such as + // those computed from a null pointer. + TrailZ = std::min(TrailZ, unsigned(sizeof(unsigned) * CHAR_BIT - 1)); + + unsigned Align = 1u << std::min(BitWidth - 1, TrailZ); + + // LLVM doesn't support alignments larger than this currently. + Align = std::min(Align, +Value::MaximumAlignment); + + if (PrefAlign > Align) + Align = enforceKnownAlignment(V, Align, PrefAlign); + + // We don't need to make any adjustment. + return Align; +} + From sabre at nondot.org Sat Dec 25 14:42:39 2010 From: sabre at nondot.org (Chris Lattner) Date: Sat, 25 Dec 2010 20:42:39 -0000 Subject: [llvm-commits] [llvm] r122555 - /llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Message-ID: <20101225204239.0B2D42A6C12C@llvm.org> Author: lattner Date: Sat Dec 25 14:42:38 2010 New Revision: 122555 URL: http://llvm.org/viewvc/llvm-project?rev=122555&view=rev Log: switch the inliner alignment enforcement stuff to use the getOrEnforceKnownAlignment function, which simplifies the code and makes it stronger. Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=122555&r1=122554&r2=122555&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Sat Dec 25 14:42:38 2010 @@ -24,6 +24,7 @@ #include "llvm/Analysis/DebugInfo.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Target/TargetData.h" +#include "llvm/Transforms/Utils/Local.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/CallSite.h" @@ -247,34 +248,14 @@ 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; - } - } + // If the pointer is already known to be sufficiently aligned, or if we can + // round it up to a larger alignment, then we don't need a temporary. + if (getOrEnforceKnownAlignment(Arg, ByValAlignment, + IFI.TD) >= ByValAlignment) + return Arg; - // Otherwise, we have to make a memcpy to get a safe alignment, pretty lame. + // Otherwise, we have to make a memcpy to get a safe alignment. This is bad + // for code quality, but rarely happens and is required for correctness. } LLVMContext &Context = Arg->getContext(); From sabre at nondot.org Sat Dec 25 14:46:07 2010 From: sabre at nondot.org (Chris Lattner) Date: Sat, 25 Dec 2010 12:46:07 -0800 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: <8FCD53AC-A859-4E1A-A902-692320F99205@nondot.org> >> + // 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; Yep, it was on my todo list. Done in r122555, thanks a lot for the great reviews. -Chris From clattner at apple.com Sat Dec 25 14:47:07 2010 From: clattner at apple.com (Chris Lattner) Date: Sat, 25 Dec 2010 12:47:07 -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: <92C5A763-DF29-4FF2-9D30-DD0A7A7B3138@apple.com> References: <20101217214549.686D72A6C12C@llvm.org> <92C5A763-DF29-4FF2-9D30-DD0A7A7B3138@apple.com> Message-ID: On Dec 20, 2010, at 11:39 AM, dalej wrote > 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! Ok, thanks, please do. -Chris -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101225/07bbb546/attachment.html From clattner at apple.com Sat Dec 25 14:48:44 2010 From: clattner at apple.com (Chris Lattner) Date: Sat, 25 Dec 2010 12:48:44 -0800 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 In-Reply-To: <20101222133608.914332A6C12C@llvm.org> References: <20101222133608.914332A6C12C@llvm.org> Message-ID: <497F8B4E-2BB3-4369-B210-763F329968F6@apple.com> On Dec 22, 2010, at 5:36 AM, Duncan Sands wrote: > 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. Hi Duncan, I'm a bit concerned about the compile time cost of this. If this isn't kicking in much, is it really worth it? Have you looked to see if this causes a compile time hit? -Chris > > 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 > } > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Sat Dec 25 14:52:05 2010 From: sabre at nondot.org (Chris Lattner) Date: Sat, 25 Dec 2010 20:52:05 -0000 Subject: [llvm-commits] [llvm] r122556 - in /llvm/trunk/lib/Transforms: InstCombine/InstCombineCalls.cpp Utils/Local.cpp Message-ID: <20101225205205.2EA4B2A6C12C@llvm.org> Author: lattner Date: Sat Dec 25 14:52:04 2010 New Revision: 122556 URL: http://llvm.org/viewvc/llvm-project?rev=122556&view=rev Log: don't lose TD info Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp llvm/trunk/lib/Transforms/Utils/Local.cpp Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=122556&r1=122555&r2=122556&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Sat Dec 25 14:52:04 2010 @@ -122,7 +122,7 @@ } Instruction *InstCombiner::SimplifyMemSet(MemSetInst *MI) { - unsigned Alignment = getKnownAlignment(MI->getDest()); + unsigned Alignment = getKnownAlignment(MI->getDest(), TD); if (MI->getAlignment() < Alignment) { MI->setAlignment(ConstantInt::get(MI->getAlignmentType(), Alignment, false)); @@ -629,7 +629,7 @@ case Intrinsic::arm_neon_vst2lane: case Intrinsic::arm_neon_vst3lane: case Intrinsic::arm_neon_vst4lane: { - unsigned MemAlign = getKnownAlignment(II->getArgOperand(0)); + unsigned MemAlign = getKnownAlignment(II->getArgOperand(0), TD); unsigned AlignArg = II->getNumArgOperands() - 1; ConstantInt *IntrAlign = dyn_cast(II->getArgOperand(AlignArg)); if (IntrAlign && IntrAlign->getZExtValue() < MemAlign) { Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=122556&r1=122555&r2=122556&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Sat Dec 25 14:52:04 2010 @@ -715,7 +715,7 @@ unsigned BitWidth = TD ? TD->getPointerSizeInBits() : 64; APInt Mask = APInt::getAllOnesValue(BitWidth); APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0); - ComputeMaskedBits(V, Mask, KnownZero, KnownOne); + ComputeMaskedBits(V, Mask, KnownZero, KnownOne, TD); unsigned TrailZ = KnownZero.countTrailingOnes(); // Avoid trouble with rediculously large TrailZ values, such as From sabre at nondot.org Sat Dec 25 15:36:35 2010 From: sabre at nondot.org (Chris Lattner) Date: Sat, 25 Dec 2010 21:36:35 -0000 Subject: [llvm-commits] [llvm] r122557 - in /llvm/trunk: lib/MC/MCParser/AsmLexer.cpp test/MC/X86/x86-64.s Message-ID: <20101225213635.3BF122A6C12C@llvm.org> Author: lattner Date: Sat Dec 25 15:36:35 2010 New Revision: 122557 URL: http://llvm.org/viewvc/llvm-project?rev=122557&view=rev Log: Generalize a previous change, fixing PR8855 - an valid large immediate rejected by the mc assembler. Modified: llvm/trunk/lib/MC/MCParser/AsmLexer.cpp llvm/trunk/test/MC/X86/x86-64.s Modified: llvm/trunk/lib/MC/MCParser/AsmLexer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmLexer.cpp?rev=122557&r1=122556&r2=122557&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCParser/AsmLexer.cpp (original) +++ llvm/trunk/lib/MC/MCParser/AsmLexer.cpp Sat Dec 25 15:36:35 2010 @@ -184,12 +184,12 @@ long long Value; if (Result.getAsInteger(10, Value)) { - // We have to handle minint_as_a_positive_value specially, because - // - minint_as_a_positive_value = minint and it is valid. - if (Result == "9223372036854775808") - Value = -9223372036854775808ULL; - else - return ReturnError(TokStart, "Invalid decimal number"); + // Allow positive values that are too large to fit into a signed 64-bit + // integer, but that do fit in an unsigned one, we just convert them over. + unsigned long long UValue; + if (Result.getAsInteger(10, UValue)) + return ReturnError(TokStart, "invalid decimal number"); + Value = (long long)UValue; } // The darwin/x86 (and x86-64) assembler accepts and ignores ULL and LL Modified: llvm/trunk/test/MC/X86/x86-64.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/x86-64.s?rev=122557&r1=122556&r2=122557&view=diff ============================================================================== --- llvm/trunk/test/MC/X86/x86-64.s (original) +++ llvm/trunk/test/MC/X86/x86-64.s Sat Dec 25 15:36:35 2010 @@ -916,3 +916,7 @@ rex64 // CHECK: rex64 # encoding: [0x48] data16 // CHECK: data16 # encoding: [0x66] + +// PR8855 +movq 18446744073709551615,%rbx // CHECK: movq -1, %rbx + From nicholas at mxc.ca Sat Dec 25 18:38:45 2010 From: nicholas at mxc.ca (Nick Lewycky) Date: Sat, 25 Dec 2010 16:38:45 -0800 Subject: [llvm-commits] [llvm] r122557 - in /llvm/trunk: lib/MC/MCParser/AsmLexer.cpp test/MC/X86/x86-64.s In-Reply-To: <20101225213635.3BF122A6C12C@llvm.org> References: <20101225213635.3BF122A6C12C@llvm.org> Message-ID: <4D168E95.1010706@mxc.ca> On 12/25/2010 01:36 PM, Chris Lattner wrote: > Author: lattner > Date: Sat Dec 25 15:36:35 2010 > New Revision: 122557 > > URL: http://llvm.org/viewvc/llvm-project?rev=122557&view=rev > Log: > Generalize a previous change, fixing PR8855 - an valid large immediate > rejected by the mc assembler. Thanks Chris!! Nick > > Modified: > llvm/trunk/lib/MC/MCParser/AsmLexer.cpp > llvm/trunk/test/MC/X86/x86-64.s > > Modified: llvm/trunk/lib/MC/MCParser/AsmLexer.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmLexer.cpp?rev=122557&r1=122556&r2=122557&view=diff > ============================================================================== > --- llvm/trunk/lib/MC/MCParser/AsmLexer.cpp (original) > +++ llvm/trunk/lib/MC/MCParser/AsmLexer.cpp Sat Dec 25 15:36:35 2010 > @@ -184,12 +184,12 @@ > > long long Value; > if (Result.getAsInteger(10, Value)) { > - // We have to handle minint_as_a_positive_value specially, because > - // - minint_as_a_positive_value = minint and it is valid. > - if (Result == "9223372036854775808") > - Value = -9223372036854775808ULL; > - else > - return ReturnError(TokStart, "Invalid decimal number"); > + // Allow positive values that are too large to fit into a signed 64-bit > + // integer, but that do fit in an unsigned one, we just convert them over. > + unsigned long long UValue; > + if (Result.getAsInteger(10, UValue)) > + return ReturnError(TokStart, "invalid decimal number"); > + Value = (long long)UValue; > } > > // The darwin/x86 (and x86-64) assembler accepts and ignores ULL and LL > > Modified: llvm/trunk/test/MC/X86/x86-64.s > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/x86-64.s?rev=122557&r1=122556&r2=122557&view=diff > ============================================================================== > --- llvm/trunk/test/MC/X86/x86-64.s (original) > +++ llvm/trunk/test/MC/X86/x86-64.s Sat Dec 25 15:36:35 2010 > @@ -916,3 +916,7 @@ > > rex64 // CHECK: rex64 # encoding: [0x48] > data16 // CHECK: data16 # encoding: [0x66] > + > +// PR8855 > +movq 18446744073709551615,%rbx // CHECK: movq -1, %rbx > + > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From sabre at nondot.org Sat Dec 25 21:53:31 2010 From: sabre at nondot.org (Chris Lattner) Date: Sun, 26 Dec 2010 03:53:31 -0000 Subject: [llvm-commits] [llvm] r122559 - /llvm/trunk/lib/Target/X86/README.txt Message-ID: <20101226035331.7AEC72A6C12C@llvm.org> Author: lattner Date: Sat Dec 25 21:53:31 2010 New Revision: 122559 URL: http://llvm.org/viewvc/llvm-project?rev=122559&view=rev Log: add a note 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=122559&r1=122558&r2=122559&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Sat Dec 25 21:53:31 2010 @@ -96,6 +96,97 @@ //===---------------------------------------------------------------------===// +This: + +void foo(void); +void bar(int x, int *P) { + x >>= 2; + if (x) + foo(); + *P = x; +} + +compiles into: + + movq %rsi, %rbx + movl %edi, %r14d + sarl $2, %r14d + testl %r14d, %r14d + je LBB0_2 + +Instead of doing an explicit test, we can use the flags off the sar. This +occurs in a bigger testcase like this, which is pretty common: + +#include + + +int test1(std::vector &X) { + int Sum = 0; + for (long i = 0, e = X.size(); i != e; ++i) + X[i] = 0; + return Sum; +} +compiles into: + + movq %rsi, %rbx + movl %edi, %r14d + sarl $2, %r14d + testl %r14d, %r14d + je LBB0_2 + +Instead of doing an explicit test, we can use the flags off the sar. This +occurs in a bigger testcase like this, which is pretty common: + +#include + + +int test1(std::vector &X) { + int Sum = 0; + for (long i = 0, e = X.size(); i != e; ++i) + X[i] = 0; + return Sum; +} +compiles into: + + movq %rsi, %rbx + movl %edi, %r14d + sarl $2, %r14d + testl %r14d, %r14d + je LBB0_2 + +Instead of doing an explicit test, we can use the flags off the sar. This +occurs in a bigger testcase like this, which is pretty common: + +#include + + +int test1(std::vector &X) { + int Sum = 0; + for (long i = 0, e = X.size(); i != e; ++i) + X[i] = 0; + return Sum; +} +compiles into: + + movq %rsi, %rbx + movl %edi, %r14d + sarl $2, %r14d + testl %r14d, %r14d + je LBB0_2 + +Instead of doing an explicit test, we can use the flags off the sar. This +occurs in a bigger testcase like this, which is pretty common in bootstrap: + +#include +int test1(std::vector &X) { + int Sum = 0; + for (long i = 0, e = X.size(); i != e; ++i) + X[i] = 0; + return Sum; +} + +//===---------------------------------------------------------------------===// + Only use inc/neg/not instructions on processors where they are faster than add/sub/xor. They are slower on the P4 due to only updating some processor flags. From nicholas at mxc.ca Sat Dec 25 22:08:46 2010 From: nicholas at mxc.ca (Nick Lewycky) Date: Sat, 25 Dec 2010 20:08:46 -0800 Subject: [llvm-commits] [llvm] r122559 - /llvm/trunk/lib/Target/X86/README.txt In-Reply-To: <20101226035331.7AEC72A6C12C@llvm.org> References: <20101226035331.7AEC72A6C12C@llvm.org> Message-ID: <4D16BFCE.7090704@mxc.ca> On 12/25/2010 07:53 PM, Chris Lattner wrote: > Author: lattner > Date: Sat Dec 25 21:53:31 2010 > New Revision: 122559 > > URL: http://llvm.org/viewvc/llvm-project?rev=122559&view=rev > Log: > add a note > > 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=122559&r1=122558&r2=122559&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/X86/README.txt (original) > +++ llvm/trunk/lib/Target/X86/README.txt Sat Dec 25 21:53:31 2010 > @@ -96,6 +96,97 @@ > > //===---------------------------------------------------------------------===// > > +This: > + > +void foo(void); > +void bar(int x, int *P) { > + x>>= 2; > + if (x) > + foo(); > + *P = x; > +} > + > +compiles into: > + > + movq %rsi, %rbx > + movl %edi, %r14d > + sarl $2, %r14d > + testl %r14d, %r14d > + je LBB0_2 > + > +Instead of doing an explicit test, we can use the flags off the sar. This > +occurs in a bigger testcase like this, which is pretty common: > + > +#include > + > + > +int test1(std::vector &X) { > + int Sum = 0; > + for (long i = 0, e = X.size(); i != e; ++i) > + X[i] = 0; > + return Sum; > +} This entry is very repetitive ;-) Nick > +compiles into: > + > + movq %rsi, %rbx > + movl %edi, %r14d > + sarl $2, %r14d > + testl %r14d, %r14d > + je LBB0_2 > + > +Instead of doing an explicit test, we can use the flags off the sar. This > +occurs in a bigger testcase like this, which is pretty common: > + > +#include > + > + > +int test1(std::vector &X) { > + int Sum = 0; > + for (long i = 0, e = X.size(); i != e; ++i) > + X[i] = 0; > + return Sum; > +} > +compiles into: > + > + movq %rsi, %rbx > + movl %edi, %r14d > + sarl $2, %r14d > + testl %r14d, %r14d > + je LBB0_2 > + > +Instead of doing an explicit test, we can use the flags off the sar. This > +occurs in a bigger testcase like this, which is pretty common: > + > +#include > + > + > +int test1(std::vector &X) { > + int Sum = 0; > + for (long i = 0, e = X.size(); i != e; ++i) > + X[i] = 0; > + return Sum; > +} > +compiles into: > + > + movq %rsi, %rbx > + movl %edi, %r14d > + sarl $2, %r14d > + testl %r14d, %r14d > + je LBB0_2 > + > +Instead of doing an explicit test, we can use the flags off the sar. This > +occurs in a bigger testcase like this, which is pretty common in bootstrap: > + > +#include > +int test1(std::vector &X) { > + int Sum = 0; > + for (long i = 0, e = X.size(); i != e; ++i) > + X[i] = 0; > + return Sum; > +} > + > +//===---------------------------------------------------------------------===// > + > Only use inc/neg/not instructions on processors where they are faster than > add/sub/xor. They are slower on the P4 due to only updating some processor > flags. > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From baldrick at free.fr Sun Dec 26 05:53:40 2010 From: baldrick at free.fr (Duncan Sands) Date: Sun, 26 Dec 2010 12:53:40 +0100 Subject: [llvm-commits] [llvm] r122548 - in /llvm/trunk: lib/Transforms/Scalar/MemCpyOptimizer.cpp test/Transforms/MemCpyOpt/memcpy-to-memset.ll In-Reply-To: <20101224211713.2176C2A6C12C@llvm.org> References: <20101224211713.2176C2A6C12C@llvm.org> Message-ID: <4D172CC4.3080200@free.fr> Hi Benjamin, > @@ -38,6 +40,13 @@ > /// i16 0xF0F0, double 0.0 etc. If the value can't be handled with a repeated > /// byte store (e.g. i16 0x1234), return null. > static Value *isBytewiseValue(Value *V) { > + // Look through constant globals. > + if (GlobalVariable *GV = dyn_cast(V)) { > + if (GV->mayBeOverridden() || !GV->isConstant() || !GV->hasInitializer()) > + return 0; this test could be simplified using GV->hasDefinitiveInitializer(). Ciao, Duncan. From sabre at nondot.org Sun Dec 26 06:05:11 2010 From: sabre at nondot.org (Chris Lattner) Date: Sun, 26 Dec 2010 12:05:11 -0000 Subject: [llvm-commits] [llvm] r122560 - /llvm/trunk/lib/Target/X86/README.txt Message-ID: <20101226120511.5D3932A6C12C@llvm.org> Author: lattner Date: Sun Dec 26 06:05:11 2010 New Revision: 122560 URL: http://llvm.org/viewvc/llvm-project?rev=122560&view=rev Log: fix some sort of weird pasto 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=122560&r1=122559&r2=122560&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Sun Dec 26 06:05:11 2010 @@ -118,66 +118,6 @@ occurs in a bigger testcase like this, which is pretty common: #include - - -int test1(std::vector &X) { - int Sum = 0; - for (long i = 0, e = X.size(); i != e; ++i) - X[i] = 0; - return Sum; -} -compiles into: - - movq %rsi, %rbx - movl %edi, %r14d - sarl $2, %r14d - testl %r14d, %r14d - je LBB0_2 - -Instead of doing an explicit test, we can use the flags off the sar. This -occurs in a bigger testcase like this, which is pretty common: - -#include - - -int test1(std::vector &X) { - int Sum = 0; - for (long i = 0, e = X.size(); i != e; ++i) - X[i] = 0; - return Sum; -} -compiles into: - - movq %rsi, %rbx - movl %edi, %r14d - sarl $2, %r14d - testl %r14d, %r14d - je LBB0_2 - -Instead of doing an explicit test, we can use the flags off the sar. This -occurs in a bigger testcase like this, which is pretty common: - -#include - - -int test1(std::vector &X) { - int Sum = 0; - for (long i = 0, e = X.size(); i != e; ++i) - X[i] = 0; - return Sum; -} -compiles into: - - movq %rsi, %rbx - movl %edi, %r14d - sarl $2, %r14d - testl %r14d, %r14d - je LBB0_2 - -Instead of doing an explicit test, we can use the flags off the sar. This -occurs in a bigger testcase like this, which is pretty common in bootstrap: - -#include int test1(std::vector &X) { int Sum = 0; for (long i = 0, e = X.size(); i != e; ++i) From benny.kra at googlemail.com Sun Dec 26 09:23:45 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Sun, 26 Dec 2010 15:23:45 -0000 Subject: [llvm-commits] [llvm] r122561 - /llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Message-ID: <20101226152345.9E5372A6C12C@llvm.org> Author: d0k Date: Sun Dec 26 09:23:45 2010 New Revision: 122561 URL: http://llvm.org/viewvc/llvm-project?rev=122561&view=rev Log: Simplify code. Modified: llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Modified: llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp?rev=122561&r1=122560&r2=122561&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Sun Dec 26 09:23:45 2010 @@ -787,7 +787,7 @@ // If copying from a constant, try to turn the memcpy into a memset. if (GlobalVariable *GV = dyn_cast(M->getSource())) - if (!GV->mayBeOverridden() && GV->isConstant() && GV->hasInitializer()) + if (GV->isConstant() && GV->hasDefinitiveInitializer()) if (Value *ByteVal = isBytewiseValue(GV->getInitializer())) { Value *Ops[] = { M->getRawDest(), ByteVal, // Start, value From sabre at nondot.org Sun Dec 26 13:32:44 2010 From: sabre at nondot.org (Chris Lattner) Date: Sun, 26 Dec 2010 19:32:44 -0000 Subject: [llvm-commits] [llvm] r122562 - in /llvm/trunk: include/llvm/InitializePasses.h include/llvm/LinkAllPasses.h include/llvm/Transforms/Scalar.h lib/Transforms/Scalar/CMakeLists.txt lib/Transforms/Scalar/Scalar.cpp Message-ID: <20101226193244.6CA012A6C12C@llvm.org> Author: lattner Date: Sun Dec 26 13:32:44 2010 New Revision: 122562 URL: http://llvm.org/viewvc/llvm-project?rev=122562&view=rev Log: Start of a pass for recognizing memset and memcpy idioms. No functionality yet. Modified: llvm/trunk/include/llvm/InitializePasses.h llvm/trunk/include/llvm/LinkAllPasses.h llvm/trunk/include/llvm/Transforms/Scalar.h llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt llvm/trunk/lib/Transforms/Scalar/Scalar.cpp Modified: llvm/trunk/include/llvm/InitializePasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=122562&r1=122561&r2=122562&view=diff ============================================================================== --- llvm/trunk/include/llvm/InitializePasses.h (original) +++ llvm/trunk/include/llvm/InitializePasses.h Sun Dec 26 13:32:44 2010 @@ -133,6 +133,7 @@ void initializeLoopStrengthReducePass(PassRegistry&); void initializeLoopUnrollPass(PassRegistry&); void initializeLoopUnswitchPass(PassRegistry&); +void initializeLoopIdiomRecognizePass(PassRegistry&); void initializeLowerAtomicPass(PassRegistry&); void initializeLowerIntrinsicsPass(PassRegistry&); void initializeLowerInvokePass(PassRegistry&); Modified: llvm/trunk/include/llvm/LinkAllPasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=122562&r1=122561&r2=122562&view=diff ============================================================================== --- llvm/trunk/include/llvm/LinkAllPasses.h (original) +++ llvm/trunk/include/llvm/LinkAllPasses.h Sun Dec 26 13:32:44 2010 @@ -90,6 +90,7 @@ (void) llvm::createLoopStrengthReducePass(); (void) llvm::createLoopUnrollPass(); (void) llvm::createLoopUnswitchPass(); + (void) llvm::createLoopIdiomPass(); (void) llvm::createLoopRotatePass(); (void) llvm::createLowerInvokePass(); (void) llvm::createLowerSetJmpPass(); Modified: llvm/trunk/include/llvm/Transforms/Scalar.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar.h?rev=122562&r1=122561&r2=122562&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Scalar.h (original) +++ llvm/trunk/include/llvm/Transforms/Scalar.h Sun Dec 26 13:32:44 2010 @@ -131,6 +131,12 @@ //===----------------------------------------------------------------------===// // +// LoopIdiom - This pass recognizes and replaces idioms in loops. +// +Pass *createLoopIdiomPass(); + +//===----------------------------------------------------------------------===// +// // PromoteMemoryToRegister - This pass is used to promote memory references to // be register references. A simple example of the transformation performed by // this pass is: Modified: llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt?rev=122562&r1=122561&r2=122562&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt (original) +++ llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt Sun Dec 26 13:32:44 2010 @@ -12,6 +12,7 @@ JumpThreading.cpp LICM.cpp LoopDeletion.cpp + LoopIdiomRecognize.cpp LoopRotation.cpp LoopStrengthReduce.cpp LoopUnrollPass.cpp Modified: llvm/trunk/lib/Transforms/Scalar/Scalar.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/Scalar.cpp?rev=122562&r1=122561&r2=122562&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/Scalar.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/Scalar.cpp Sun Dec 26 13:32:44 2010 @@ -44,6 +44,7 @@ initializeLoopStrengthReducePass(Registry); initializeLoopUnrollPass(Registry); initializeLoopUnswitchPass(Registry); + initializeLoopIdiomRecognizePass(Registry); initializeLowerAtomicPass(Registry); initializeMemCpyOptPass(Registry); initializeReassociatePass(Registry); From sabre at nondot.org Sun Dec 26 13:39:38 2010 From: sabre at nondot.org (Chris Lattner) Date: Sun, 26 Dec 2010 19:39:38 -0000 Subject: [llvm-commits] [llvm] r122563 - /llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Message-ID: <20101226193938.69FCF2A6C12C@llvm.org> Author: lattner Date: Sun Dec 26 13:39:38 2010 New Revision: 122563 URL: http://llvm.org/viewvc/llvm-project?rev=122563&view=rev Log: actually add the file... Added: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Added: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=122563&view=auto ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (added) +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Sun Dec 26 13:39:38 2010 @@ -0,0 +1,103 @@ +//===-- LoopIdiomRecognize.cpp - Loop idiom recognition -------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass implements an idiom recognizer that transforms simple loops into a +// non-loop form. In cases that this kicks in, it can be a significant +// performance win. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "loop-idiom" +#include "llvm/Transforms/Scalar.h" +#include "llvm/Analysis/LoopPass.h" +#include "llvm/Analysis/ScalarEvolutionExpressions.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; + +// TODO: Recognize "N" size array multiplies: replace with call to blas or +// something. + +namespace { + class LoopIdiomRecognize : public LoopPass { + public: + static char ID; + explicit LoopIdiomRecognize() : LoopPass(ID) { + initializeLoopIdiomRecognizePass(*PassRegistry::getPassRegistry()); + } + + bool runOnLoop(Loop *L, LPPassManager &LPM); + + bool scanBlock(BasicBlock *BB, Loop *L); + + /// This transformation requires natural loop information & requires that + /// loop preheaders be inserted into the CFG. + /// + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + AU.addPreserved(); + AU.addRequiredID(LoopSimplifyID); + AU.addPreservedID(LoopSimplifyID); + AU.addRequiredID(LCSSAID); + AU.addPreservedID(LCSSAID); + AU.addRequired(); + AU.addPreserved(); + AU.addPreserved(); + } + }; +} + +char LoopIdiomRecognize::ID = 0; +INITIALIZE_PASS_BEGIN(LoopIdiomRecognize, "loop-idiom", "Recognize loop idioms", + false, false) +INITIALIZE_PASS_DEPENDENCY(LoopInfo) +INITIALIZE_PASS_DEPENDENCY(LoopSimplify) +INITIALIZE_PASS_DEPENDENCY(LCSSA) +INITIALIZE_PASS_DEPENDENCY(ScalarEvolution) +INITIALIZE_PASS_END(LoopIdiomRecognize, "loop-idiom", "Recognize loop idioms", + false, false) + +Pass *llvm::createLoopIdiomPass() { return new LoopIdiomRecognize(); } + +bool LoopIdiomRecognize::runOnLoop(Loop *L, LPPassManager &LPM) { + // We only look at trivial single basic block loops. + // TODO: eventually support more complex loops, scanning the header. + if (L->getBlocks().size() != 1) + return false; + + BasicBlock *BB = L->getHeader(); + DEBUG(dbgs() << "Loop Idiom Recognize: F[" << BB->getParent()->getName() + << "] Loop %" << BB->getName() << "\n"); + + return scanBlock(BB, L); +} + +/// scanBlock - Look over a block to see if we can promote anything out of it. +bool LoopIdiomRecognize::scanBlock(BasicBlock *BB, Loop *L) { + ScalarEvolution &SE = getAnalysis(); + + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { + // Look for store instructions, which may be memsets. + StoreInst *SI = dyn_cast(I++); + if (SI == 0) continue; + + // See if the pointer expression is an AddRec like {base,+,1} on the current + // loop, which indicates a strided store. If we have something else, it's a + // random store we can't handle. + const SCEVAddRecExpr *Ev = + dyn_cast(SE.getSCEV(SI->getPointerOperand())); + if (Ev == 0 || Ev->getLoop() != L) + continue; + + errs() << "Found strided store: " << *Ev << "\n"; + } + + return false; +} + From sabre at nondot.org Sun Dec 26 14:15:01 2010 From: sabre at nondot.org (Chris Lattner) Date: Sun, 26 Dec 2010 20:15:01 -0000 Subject: [llvm-commits] [llvm] r122565 - in /llvm/trunk: include/llvm/Analysis/ValueTracking.h lib/Analysis/ValueTracking.cpp lib/Transforms/Scalar/MemCpyOptimizer.cpp Message-ID: <20101226201501.73B582A6C12C@llvm.org> Author: lattner Date: Sun Dec 26 14:15:01 2010 New Revision: 122565 URL: http://llvm.org/viewvc/llvm-project?rev=122565&view=rev Log: move isBytewiseValue out to ValueTracking.h/cpp Modified: llvm/trunk/include/llvm/Analysis/ValueTracking.h llvm/trunk/lib/Analysis/ValueTracking.cpp llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Modified: llvm/trunk/include/llvm/Analysis/ValueTracking.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ValueTracking.h?rev=122565&r1=122564&r2=122565&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ValueTracking.h (original) +++ llvm/trunk/include/llvm/Analysis/ValueTracking.h Sun Dec 26 14:15:01 2010 @@ -77,7 +77,13 @@ /// bool CannotBeNegativeZero(const Value *V, unsigned Depth = 0); - + /// isBytewiseValue - If the specified value can be set by repeating the same + /// byte in memory, return the i8 value that it is represented with. This is + /// true for all i8 values obviously, but is also true for i32 0, i32 -1, + /// i16 0xF0F0, double 0.0 etc. If the value can't be handled with a repeated + /// byte store (e.g. i16 0x1234), return null. + Value *isBytewiseValue(Value *V); + /// FindInsertedValue - Given an aggregrate and an sequence of indices, see if /// the scalar value indexed is already around as a register, for example if /// it were inserted directly into the aggregrate. Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=122565&r1=122564&r2=122565&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ValueTracking.cpp (original) +++ llvm/trunk/lib/Analysis/ValueTracking.cpp Sun Dec 26 14:15:01 2010 @@ -989,6 +989,75 @@ return false; } +/// isBytewiseValue - If the specified value can be set by repeating the same +/// byte in memory, return the i8 value that it is represented with. This is +/// true for all i8 values obviously, but is also true for i32 0, i32 -1, +/// i16 0xF0F0, double 0.0 etc. If the value can't be handled with a repeated +/// byte store (e.g. i16 0x1234), return null. +Value *llvm::isBytewiseValue(Value *V) { + // All byte-wide stores are splatable, even of arbitrary variables. + if (V->getType()->isIntegerTy(8)) return V; + + // Constant float and double values can be handled as integer values if the + // corresponding integer value is "byteable". An important case is 0.0. + if (ConstantFP *CFP = dyn_cast(V)) { + if (CFP->getType()->isFloatTy()) + V = ConstantExpr::getBitCast(CFP, Type::getInt32Ty(V->getContext())); + if (CFP->getType()->isDoubleTy()) + V = ConstantExpr::getBitCast(CFP, Type::getInt64Ty(V->getContext())); + // Don't handle long double formats, which have strange constraints. + } + + // We can handle constant integers that are power of two in size and a + // multiple of 8 bits. + if (ConstantInt *CI = dyn_cast(V)) { + unsigned Width = CI->getBitWidth(); + if (isPowerOf2_32(Width) && Width > 8) { + // We can handle this value if the recursive binary decomposition is the + // same at all levels. + APInt Val = CI->getValue(); + APInt Val2; + while (Val.getBitWidth() != 8) { + unsigned NextWidth = Val.getBitWidth()/2; + Val2 = Val.lshr(NextWidth); + Val2 = Val2.trunc(Val.getBitWidth()/2); + Val = Val.trunc(Val.getBitWidth()/2); + + // If the top/bottom halves aren't the same, reject it. + if (Val != Val2) + return 0; + } + return ConstantInt::get(V->getContext(), Val); + } + } + + // A ConstantArray is splatable if all its members are equal and also + // splatable. + if (ConstantArray *CA = dyn_cast(V)) { + if (CA->getNumOperands() == 0) + return 0; + + Value *Val = isBytewiseValue(CA->getOperand(0)); + if (!Val) + return 0; + + for (unsigned I = 1, E = CA->getNumOperands(); I != E; ++I) + if (CA->getOperand(I-1) != CA->getOperand(I)) + return 0; + + return Val; + } + + // Conceptually, we could handle things like: + // %a = zext i8 %X to i16 + // %b = shl i16 %a, 8 + // %c = or i16 %a, %b + // but until there is an example that actually needs this, it doesn't seem + // worth worrying about. + return 0; +} + + // This is the recursive version of BuildSubAggregate. It takes a few different // arguments. Idxs is the index within the nested struct From that we are // looking at now (which is of type IndexedType). IdxSkip is the number of Modified: llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp?rev=122565&r1=122564&r2=122565&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Sun Dec 26 14:15:01 2010 @@ -22,6 +22,7 @@ #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/MemoryDependenceAnalysis.h" +#include "llvm/Analysis/ValueTracking.h" #include "llvm/Support/Debug.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/raw_ostream.h" @@ -34,74 +35,6 @@ STATISTIC(NumMoveToCpy, "Number of memmoves converted to memcpy"); STATISTIC(NumCpyToSet, "Number of memcpys converted to memset"); -/// isBytewiseValue - If the specified value can be set by repeating the same -/// byte in memory, return the i8 value that it is represented with. This is -/// true for all i8 values obviously, but is also true for i32 0, i32 -1, -/// i16 0xF0F0, double 0.0 etc. If the value can't be handled with a repeated -/// byte store (e.g. i16 0x1234), return null. -static Value *isBytewiseValue(Value *V) { - // All byte-wide stores are splatable, even of arbitrary variables. - if (V->getType()->isIntegerTy(8)) return V; - - // Constant float and double values can be handled as integer values if the - // corresponding integer value is "byteable". An important case is 0.0. - if (ConstantFP *CFP = dyn_cast(V)) { - if (CFP->getType()->isFloatTy()) - V = ConstantExpr::getBitCast(CFP, Type::getInt32Ty(V->getContext())); - if (CFP->getType()->isDoubleTy()) - V = ConstantExpr::getBitCast(CFP, Type::getInt64Ty(V->getContext())); - // Don't handle long double formats, which have strange constraints. - } - - // We can handle constant integers that are power of two in size and a - // multiple of 8 bits. - if (ConstantInt *CI = dyn_cast(V)) { - unsigned Width = CI->getBitWidth(); - if (isPowerOf2_32(Width) && Width > 8) { - // We can handle this value if the recursive binary decomposition is the - // same at all levels. - APInt Val = CI->getValue(); - APInt Val2; - while (Val.getBitWidth() != 8) { - unsigned NextWidth = Val.getBitWidth()/2; - Val2 = Val.lshr(NextWidth); - Val2 = Val2.trunc(Val.getBitWidth()/2); - Val = Val.trunc(Val.getBitWidth()/2); - - // If the top/bottom halves aren't the same, reject it. - if (Val != Val2) - return 0; - } - return ConstantInt::get(V->getContext(), Val); - } - } - - // A ConstantArray is splatable if all its members are equal and also - // splatable. - if (ConstantArray *CA = dyn_cast(V)) { - if (CA->getNumOperands() == 0) - return 0; - - Value *Val = isBytewiseValue(CA->getOperand(0)); - if (!Val) - return 0; - - for (unsigned I = 1, E = CA->getNumOperands(); I != E; ++I) - if (CA->getOperand(I-1) != CA->getOperand(I)) - return 0; - - return Val; - } - - // Conceptually, we could handle things like: - // %a = zext i8 %X to i16 - // %b = shl i16 %a, 8 - // %c = or i16 %a, %b - // but until there is an example that actually needs this, it doesn't seem - // worth worrying about. - return 0; -} - static int64_t GetOffsetFromIndex(const GetElementPtrInst *GEP, unsigned Idx, bool &VariableIdxFound, TargetData &TD) { // Skip over the first indices. From rafael.espindola at gmail.com Sun Dec 26 14:20:31 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Sun, 26 Dec 2010 20:20:31 -0000 Subject: [llvm-commits] [llvm] r122566 - in /llvm/trunk: include/llvm/MC/MCStreamer.h lib/MC/MCDwarf.cpp lib/MC/MCELFStreamer.cpp lib/MC/MCParser/AsmParser.cpp test/MC/ELF/cfi.s Message-ID: <20101226202031.84AED2A6C12C@llvm.org> Author: rafael Date: Sun Dec 26 14:20:31 2010 New Revision: 122566 URL: http://llvm.org/viewvc/llvm-project?rev=122566&view=rev Log: Add basic support for .cfi_personality. Modified: llvm/trunk/include/llvm/MC/MCStreamer.h llvm/trunk/lib/MC/MCDwarf.cpp llvm/trunk/lib/MC/MCELFStreamer.cpp llvm/trunk/lib/MC/MCParser/AsmParser.cpp llvm/trunk/test/MC/ELF/cfi.s Modified: llvm/trunk/include/llvm/MC/MCStreamer.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=122566&r1=122565&r2=122566&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCStreamer.h (original) +++ llvm/trunk/include/llvm/MC/MCStreamer.h Sun Dec 26 14:20:31 2010 @@ -52,6 +52,10 @@ void EmitSymbolValue(const MCSymbol *Sym, unsigned Size, bool isPCRel, unsigned AddrSpace); + std::vector FrameInfos; + MCDwarfFrameInfo *getCurrentFrameInfo(); + void EnsureValidFrame(); + protected: MCStreamer(MCContext &Ctx); @@ -63,10 +67,6 @@ /// is kept up to date by SwitchSection. const MCSection *PrevSection; - std::vector FrameInfos; - MCDwarfFrameInfo *getCurrentFrameInfo(); - void EnsureValidFrame(); - public: virtual ~MCStreamer(); Modified: llvm/trunk/lib/MC/MCDwarf.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf.cpp?rev=122566&r1=122565&r2=122566&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCDwarf.cpp (original) +++ llvm/trunk/lib/MC/MCDwarf.cpp Sun Dec 26 14:20:31 2010 @@ -475,8 +475,8 @@ streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_offset, 1); } else { streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1); - streamer.EmitULEB128IntValue(asmInfo.getDwarfRegNum(Src.getReg(), isEH), - 1); + streamer.EmitULEB128IntValue(asmInfo.getDwarfRegNum(Src.getReg(), + isEH)); } streamer.EmitULEB128IntValue(-Src.getOffset(), 1); @@ -508,7 +508,8 @@ } } -static const MCSymbol &EmitCIE(MCStreamer &streamer) { +static const MCSymbol &EmitCIE(MCStreamer &streamer, + const MCSymbol *personality) { MCContext &context = streamer.getContext(); const TargetAsmInfo &asmInfo = context.getTargetAsmInfo(); const MCSection §ion = *asmInfo.getEHFrameSection(); @@ -530,7 +531,10 @@ // Augmentation String SmallString<8> Augmentation; - Augmentation += "zR"; + Augmentation += "z"; + if (personality) + Augmentation += "P"; + Augmentation += "R"; streamer.EmitBytes(Augmentation.str(), 0); streamer.EmitIntValue(0, 1); @@ -553,6 +557,13 @@ // Augmentation Data (optional) streamer.EmitLabel(augmentationStart); + if (personality) { + // Personality Encoding + streamer.EmitIntValue(dwarf::DW_EH_PE_absptr, 1); + // Personality + streamer.EmitSymbolValue(personality, 8); + } + // Encoding of the FDE pointers streamer.EmitIntValue(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4, 1); streamer.EmitLabel(augmentationEnd); @@ -563,7 +574,7 @@ EmitFrameMoves(streamer, Moves, NULL, true); // Padding - streamer.EmitValueToAlignment(asmInfo.getPointerSize()); + streamer.EmitValueToAlignment(4); streamer.EmitLabel(sectionEnd); return *sectionStart; @@ -608,13 +619,19 @@ void MCDwarfFrameEmitter::Emit(MCStreamer &streamer) { const MCContext &context = streamer.getContext(); const TargetAsmInfo &asmInfo = context.getTargetAsmInfo(); - const MCSymbol &cieStart = EmitCIE(streamer); MCSymbol *fdeEnd = NULL; + DenseMap Personalities; + for (unsigned i = 0, n = streamer.getNumFrameInfos(); i < n; ++i) { - fdeEnd = EmitFDE(streamer, cieStart, streamer.getFrameInfo(i)); + const MCDwarfFrameInfo &frame = streamer.getFrameInfo(i); + const MCSymbol *&cieStart = Personalities[frame.Personality]; + if (!cieStart) + cieStart = &EmitCIE(streamer, frame.Personality); + fdeEnd = EmitFDE(streamer, *cieStart, frame); if (i != n - 1) streamer.EmitLabel(fdeEnd); } + streamer.EmitValueToAlignment(asmInfo.getPointerSize()); if (fdeEnd) streamer.EmitLabel(fdeEnd); Modified: llvm/trunk/lib/MC/MCELFStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCELFStreamer.cpp?rev=122566&r1=122565&r2=122566&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCELFStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCELFStreamer.cpp Sun Dec 26 14:20:31 2010 @@ -488,7 +488,7 @@ } void MCELFStreamer::Finish() { - if (!FrameInfos.empty()) + if (getNumFrameInfos()) MCDwarfFrameEmitter::Emit(*this); for (std::vector::const_iterator i = LocalCommons.begin(), Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=122566&r1=122565&r2=122566&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original) +++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Sun Dec 26 14:20:31 2010 @@ -2206,6 +2206,29 @@ return getStreamer().EmitCFIOffset(Register, Offset); } +static bool isValidEncoding(int64_t Encoding) { + if (Encoding & ~0xff) + return false; + + if (Encoding == dwarf::DW_EH_PE_omit) + return true; + + const unsigned Format = Encoding & 0xf; + if (Format != dwarf::DW_EH_PE_absptr && Format != dwarf::DW_EH_PE_udata2 && + Format != dwarf::DW_EH_PE_udata4 && Format != dwarf::DW_EH_PE_udata8 && + Format != dwarf::DW_EH_PE_sdata2 && Format != dwarf::DW_EH_PE_sdata4 && + Format != dwarf::DW_EH_PE_sdata8 && Format != dwarf::DW_EH_PE_signed) + return false; + + const unsigned Application = Encoding & 0xf0; + if (Application != dwarf::DW_EH_PE_absptr && + Application != dwarf::DW_EH_PE_pcrel && + Application != dwarf::DW_EH_PE_indirect) + return false; + + return true; +} + /// ParseDirectiveCFIPersonalityOrLsda /// ::= .cfi_personality encoding, [symbol_name] /// ::= .cfi_lsda encoding, [symbol_name] @@ -2214,10 +2237,10 @@ int64_t Encoding = 0; if (getParser().ParseAbsoluteExpression(Encoding)) return true; - if (Encoding == 255) + if (Encoding == dwarf::DW_EH_PE_omit) return false; - if (Encoding != 0) + if (!isValidEncoding(Encoding)) return TokError("unsupported encoding."); if (getLexer().isNot(AsmToken::Comma)) Modified: llvm/trunk/test/MC/ELF/cfi.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/cfi.s?rev=122566&r1=122565&r2=122566&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/cfi.s (original) +++ llvm/trunk/test/MC/ELF/cfi.s Sun Dec 26 14:20:31 2010 @@ -7,6 +7,18 @@ f2: .cfi_startproc + .cfi_personality 0x00, foo + nop + .cfi_endproc + +f3: + .cfi_startproc + nop + .cfi_endproc + +f4: + .cfi_startproc + .cfi_personality 0x00, foo nop .cfi_endproc @@ -16,12 +28,12 @@ // CHECK-NEXT: ('sh_flags', 0x00000002) // CHECK-NEXT: ('sh_addr', 0x00000000) // CHECK-NEXT: ('sh_offset', 0x00000048) -// CHECK-NEXT: ('sh_size', 0x00000040) +// CHECK-NEXT: ('sh_size', 0x00000088) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) // CHECK-NEXT: ('sh_addralign', 0x00000008) // CHECK-NEXT: ('sh_entsize', 0x00000000) -// CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 10000000 1c000000 00000000 01000000 00000000 10000000 30000000 00000000 01000000 00000000') +// CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 10000000 1c000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a000000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 10000000 64000000 00000000 01000000 00000000 10000000 4c000000 00000000 01000000 00000000') // CHECK-NEXT: ), // CHECK: # Section 0x00000008 @@ -29,8 +41,8 @@ // CHECK-NEXT: ('sh_type', 0x00000004) // CHECK-NEXT: ('sh_flags', 0x00000000) // CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000180) -// CHECK-NEXT: ('sh_size', 0x00000030) +// CHECK-NEXT: ('sh_offset', 0x00000220) +// CHECK-NEXT: ('sh_size', 0x00000078) // CHECK-NEXT: ('sh_link', 0x00000006) // CHECK-NEXT: ('sh_info', 0x00000004) // CHECK-NEXT: ('sh_addralign', 0x00000008) @@ -38,15 +50,33 @@ // CHECK-NEXT: ('_relocations', [ // CHECK-NEXT: # Relocation 0x00000000 // CHECK-NEXT: (('r_offset', 0x00000020) -// CHECK-NEXT: ('r_sym', 0x00000003) +// CHECK-NEXT: ('r_sym', 0x00000005) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000001 -// CHECK-NEXT: (('r_offset', 0x00000034) -// CHECK-NEXT: ('r_sym', 0x00000003) +// CHECK-NEXT: (('r_offset', 0x0000003e) +// CHECK-NEXT: ('r_sym', 0x00000009) +// CHECK-NEXT: ('r_type', 0x00000001) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000002 +// CHECK-NEXT: (('r_offset', 0x00000054) +// CHECK-NEXT: ('r_sym', 0x00000005) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000001) // CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000003 +// CHECK-NEXT: (('r_offset', 0x00000068) +// CHECK-NEXT: ('r_sym', 0x00000005) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000002) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000004 +// CHECK-NEXT: (('r_offset', 0x0000007c) +// CHECK-NEXT: ('r_sym', 0x00000005) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000003) +// CHECK-NEXT: ), // CHECK-NEXT: ]) // CHECK-NEXT: ), From sabre at nondot.org Sun Dec 26 14:45:46 2010 From: sabre at nondot.org (Chris Lattner) Date: Sun, 26 Dec 2010 20:45:46 -0000 Subject: [llvm-commits] [llvm] r122567 - /llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Message-ID: <20101226204546.0E4402A6C12C@llvm.org> Author: lattner Date: Sun Dec 26 14:45:45 2010 New Revision: 122567 URL: http://llvm.org/viewvc/llvm-project?rev=122567&view=rev Log: sketch more of this out. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=122567&r1=122566&r2=122567&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Sun Dec 26 14:45:45 2010 @@ -17,6 +17,8 @@ #include "llvm/Transforms/Scalar.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h" +#include "llvm/Analysis/ValueTracking.h" +#include "llvm/Target/TargetData.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -26,6 +28,9 @@ namespace { class LoopIdiomRecognize : public LoopPass { + Loop *CurLoop; + const TargetData *TD; + ScalarEvolution *SE; public: static char ID; explicit LoopIdiomRecognize() : LoopPass(ID) { @@ -34,7 +39,7 @@ bool runOnLoop(Loop *L, LPPassManager &LPM); - bool scanBlock(BasicBlock *BB, Loop *L); + bool processLoopStore(StoreInst *SI, const SCEV *BECount); /// This transformation requires natural loop information & requires that /// loop preheaders be inserted into the CFG. @@ -66,38 +71,77 @@ Pass *llvm::createLoopIdiomPass() { return new LoopIdiomRecognize(); } bool LoopIdiomRecognize::runOnLoop(Loop *L, LPPassManager &LPM) { + CurLoop = L; + // We only look at trivial single basic block loops. // TODO: eventually support more complex loops, scanning the header. if (L->getBlocks().size() != 1) return false; + // The trip count of the loop must be analyzable. + SE = &getAnalysis(); + if (!SE->hasLoopInvariantBackedgeTakenCount(L)) + return false; + const SCEV *BECount = SE->getBackedgeTakenCount(L); + if (isa(BECount)) return false; + + // We require target data for now. + TD = getAnalysisIfAvailable(); + if (TD == 0) return false; + BasicBlock *BB = L->getHeader(); - DEBUG(dbgs() << "Loop Idiom Recognize: F[" << BB->getParent()->getName() + DEBUG(dbgs() << "loop-idiom Scanning: F[" << BB->getParent()->getName() << "] Loop %" << BB->getName() << "\n"); - return scanBlock(BB, L); + bool MadeChange = false; + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { + // Look for store instructions, which may be memsets. + if (StoreInst *SI = dyn_cast(I++)) + MadeChange |= processLoopStore(SI, BECount); + } + + return MadeChange; } /// scanBlock - Look over a block to see if we can promote anything out of it. -bool LoopIdiomRecognize::scanBlock(BasicBlock *BB, Loop *L) { - ScalarEvolution &SE = getAnalysis(); +bool LoopIdiomRecognize::processLoopStore(StoreInst *SI, const SCEV *BECount) { + Value *StoredVal = SI->getValueOperand(); - for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { - // Look for store instructions, which may be memsets. - StoreInst *SI = dyn_cast(I++); - if (SI == 0) continue; - - // See if the pointer expression is an AddRec like {base,+,1} on the current - // loop, which indicates a strided store. If we have something else, it's a - // random store we can't handle. - const SCEVAddRecExpr *Ev = - dyn_cast(SE.getSCEV(SI->getPointerOperand())); - if (Ev == 0 || Ev->getLoop() != L) - continue; - - errs() << "Found strided store: " << *Ev << "\n"; - } + // Check to see if the store updates all bits in memory. We don't want to + // process things like a store of i3. We also require that the store be a + // multiple of a byte. + uint64_t SizeInBits = TD->getTypeSizeInBits(StoredVal->getType()); + if ((SizeInBits & 7) || (SizeInBits >> 32) != 0 || + SizeInBits != TD->getTypeStoreSizeInBits(StoredVal->getType())) + return false; + + // See if the pointer expression is an AddRec like {base,+,1} on the current + // loop, which indicates a strided store. If we have something else, it's a + // random store we can't handle. + const SCEVAddRecExpr *Ev = + dyn_cast(SE->getSCEV(SI->getPointerOperand())); + if (Ev == 0 || Ev->getLoop() != CurLoop || !Ev->isAffine()) + return false; + + // Check to see if the stride matches the size of the store. If so, then we + // know that every byte is touched in the loop. + unsigned StoreSize = (unsigned)SizeInBits >> 3; + const SCEVConstant *Stride = dyn_cast(Ev->getOperand(1)); + if (Stride == 0 || StoreSize != Stride->getValue()->getValue()) + return false; + errs() << "Found strided store: " << *Ev << "\n"; + + // Check for memcpy here. + + + // If the stored value is a byte-wise value (like i32 -1), then it may be + // turned into a memset of i8 -1, assuming that all the consequtive bytes + // are stored. A store of i32 0x01020304 can never be turned into a memset. + Value *SplatValue = isBytewiseValue(StoredVal); + if (SplatValue == 0) return false; + + return false; } From baldrick at free.fr Sun Dec 26 15:08:08 2010 From: baldrick at free.fr (Duncan Sands) Date: Sun, 26 Dec 2010 22:08:08 +0100 Subject: [llvm-commits] [llvm] r122567 - /llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp In-Reply-To: <20101226204546.0E4402A6C12C@llvm.org> References: <20101226204546.0E4402A6C12C@llvm.org> Message-ID: <4D17AEB8.5040402@free.fr> Hi Chris, > + // Check to see if the store updates all bits in memory. We don't want to > + // process things like a store of i3. We also require that the store be a > + // multiple of a byte. > + uint64_t SizeInBits = TD->getTypeSizeInBits(StoredVal->getType()); > + if ((SizeInBits& 7) || (SizeInBits>> 32) != 0 || > + SizeInBits != TD->getTypeStoreSizeInBits(StoredVal->getType())) > + return false; will this catch the case of storing a first class struct or array? Ciao, Duncan. From rafael.espindola at gmail.com Sun Dec 26 15:30:59 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Sun, 26 Dec 2010 21:30:59 -0000 Subject: [llvm-commits] [llvm] r122568 - in /llvm/trunk: lib/MC/ELFObjectWriter.cpp lib/MC/MCParser/ELFAsmParser.cpp lib/MC/MCSectionELF.cpp test/MC/ELF/section.s Message-ID: <20101226213059.49F962A6C12C@llvm.org> Author: rafael Date: Sun Dec 26 15:30:59 2010 New Revision: 122568 URL: http://llvm.org/viewvc/llvm-project?rev=122568&view=rev Log: Add support for @note. Patch by J?rg Sonnenberger. Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp llvm/trunk/lib/MC/MCSectionELF.cpp llvm/trunk/test/MC/ELF/section.s Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=122568&r1=122567&r2=122568&view=diff ============================================================================== --- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Sun Dec 26 15:30:59 2010 @@ -1265,6 +1265,7 @@ case ELF::SHT_PROGBITS: case ELF::SHT_STRTAB: case ELF::SHT_NOBITS: + case ELF::SHT_NOTE: case ELF::SHT_NULL: case ELF::SHT_ARM_ATTRIBUTES: // Nothing to do. Modified: llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp?rev=122568&r1=122567&r2=122568&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp (original) +++ llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp Sun Dec 26 15:30:59 2010 @@ -335,6 +335,8 @@ Type = MCSectionELF::SHT_NOBITS; else if (TypeName == "progbits") Type = MCSectionELF::SHT_PROGBITS; + else if (TypeName == "note") + Type = MCSectionELF::SHT_NOTE; else return TokError("unknown section type"); } Modified: llvm/trunk/lib/MC/MCSectionELF.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCSectionELF.cpp?rev=122568&r1=122567&r2=122568&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCSectionELF.cpp (original) +++ llvm/trunk/lib/MC/MCSectionELF.cpp Sun Dec 26 15:30:59 2010 @@ -92,6 +92,8 @@ OS << "preinit_array"; else if (Type == MCSectionELF::SHT_NOBITS) OS << "nobits"; + else if (Type == MCSectionELF::SHT_NOTE) + OS << "note"; else if (Type == MCSectionELF::SHT_PROGBITS) OS << "progbits"; Modified: llvm/trunk/test/MC/ELF/section.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/section.s?rev=122568&r1=122567&r2=122568&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/section.s (original) +++ llvm/trunk/test/MC/ELF/section.s Sun Dec 26 15:30:59 2010 @@ -12,7 +12,7 @@ // CHECK: ('sh_name', 0x00000033) # '.note.GNU-' // CHECK: ('sh_name', 0x0000003e) # '-.note.GNU' -// Test that the dafults are used +// Test that the defaults are used .section .init .section .fini @@ -67,6 +67,19 @@ // CHECK-NEXT: ('sh_entsize', 0x00000000) // CHECK-NEXT: ), +.section .note.test,"", at note +// CHECK: (('sh_name', 0x00000061) # '.note.test' +// CHECK-NEXT: ('sh_type', 0x00000007) +// CHECK-NEXT: ('sh_flags', 0x00000000) +// CHECK-NEXT: ('sh_addr', 0x00000000) +// CHECK-NEXT: ('sh_offset', 0x00000050) +// CHECK-NEXT: ('sh_size', 0x00000000) +// CHECK-NEXT: ('sh_link', 0x00000000) +// CHECK-NEXT: ('sh_info', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x00000001) +// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ), + // Test that we can parse these foo: bar: From clattner at apple.com Sun Dec 26 16:10:38 2010 From: clattner at apple.com (Chris Lattner) Date: Sun, 26 Dec 2010 14:10:38 -0800 Subject: [llvm-commits] [llvm] r122567 - /llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp In-Reply-To: <4D17AEB8.5040402@free.fr> References: <20101226204546.0E4402A6C12C@llvm.org> <4D17AEB8.5040402@free.fr> Message-ID: <7CF76E3A-19BA-4B23-B9FB-EAA223BDDCA8@apple.com> On Dec 26, 2010, at 1:08 PM, Duncan Sands wrote: > Hi Chris, > >> + // Check to see if the store updates all bits in memory. We don't want to >> + // process things like a store of i3. We also require that the store be a >> + // multiple of a byte. >> + uint64_t SizeInBits = TD->getTypeSizeInBits(StoredVal->getType()); >> + if ((SizeInBits& 7) || (SizeInBits>> 32) != 0 || >> + SizeInBits != TD->getTypeStoreSizeInBits(StoredVal->getType())) >> + return false; > > will this catch the case of storing a first class struct or array? I'm not sure what you mean. My intent is to start simple and just handle strided stores that satisfy isBytewiseValue. There are many interesting forms of loops that aren't like this, they will be added over time. -Chris From rafael.espindola at gmail.com Sun Dec 26 16:47:38 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Sun, 26 Dec 2010 22:47:38 -0000 Subject: [llvm-commits] [llvm] r122570 - /llvm/trunk/lib/MC/MCDwarf.cpp Message-ID: <20101226224738.0EFCA2A6C12C@llvm.org> Author: rafael Date: Sun Dec 26 16:47:37 2010 New Revision: 122570 URL: http://llvm.org/viewvc/llvm-project?rev=122570&view=rev Log: Fix .cfi_personality on 32 bit systems. Modified: llvm/trunk/lib/MC/MCDwarf.cpp Modified: llvm/trunk/lib/MC/MCDwarf.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf.cpp?rev=122570&r1=122569&r2=122570&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCDwarf.cpp (original) +++ llvm/trunk/lib/MC/MCDwarf.cpp Sun Dec 26 16:47:37 2010 @@ -561,7 +561,7 @@ // Personality Encoding streamer.EmitIntValue(dwarf::DW_EH_PE_absptr, 1); // Personality - streamer.EmitSymbolValue(personality, 8); + streamer.EmitSymbolValue(personality, asmInfo.getPointerSize()); } // Encoding of the FDE pointers streamer.EmitIntValue(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4, 1); From sabre at nondot.org Sun Dec 26 16:49:26 2010 From: sabre at nondot.org (Chris Lattner) Date: Sun, 26 Dec 2010 22:49:26 -0000 Subject: [llvm-commits] [llvm] r122571 - in /llvm/trunk: include/llvm/Support/IRBuilder.h lib/VMCore/IRBuilder.cpp Message-ID: <20101226224926.27AAF2A6C12C@llvm.org> Author: lattner Date: Sun Dec 26 16:49:25 2010 New Revision: 122571 URL: http://llvm.org/viewvc/llvm-project?rev=122571&view=rev Log: add methods to IRBuilder to create memcpy/memset/memmove. Modified: llvm/trunk/include/llvm/Support/IRBuilder.h llvm/trunk/lib/VMCore/IRBuilder.cpp Modified: llvm/trunk/include/llvm/Support/IRBuilder.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/IRBuilder.h?rev=122571&r1=122570&r2=122571&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/IRBuilder.h (original) +++ llvm/trunk/include/llvm/Support/IRBuilder.h Sun Dec 26 16:49:25 2010 @@ -235,13 +235,48 @@ return Type::getVoidTy(Context); } - const PointerType *getInt8PtrTy() { - return Type::getInt8PtrTy(Context); + const PointerType *getInt8PtrTy(unsigned AddrSpace = 0) { + return Type::getInt8PtrTy(Context, AddrSpace); } /// getCurrentFunctionReturnType - Get the return type of the current function /// that we're emitting into. const Type *getCurrentFunctionReturnType() const; + + /// CreateMemSet - Create and insert a memset to the specified pointer and the + /// specified value. If the pointer isn't an i8*, it will be converted. If a + /// TBAA tag is specified, it will be added to the instruction. + CallInst *CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, unsigned Align, + bool isVolatile = false, MDNode *TBAATag = 0) { + return CreateMemSet(Ptr, Val, getInt64(Size), Align, isVolatile, TBAATag); + } + + CallInst *CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align, + bool isVolatile = false, MDNode *TBAATag = 0); + + /// CreateMemCpy - Create and insert a memcpy between the specified pointers. + /// If the pointers aren't i8*, they will be converted. If a TBAA tag is + /// specified, it will be added to the instruction. + CallInst *CreateMemCpy(Value *Dst, Value *Src, uint64_t Size, unsigned Align, + bool isVolatile = false, MDNode *TBAATag = 0) { + return CreateMemCpy(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag); + } + + CallInst *CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align, + bool isVolatile = false, MDNode *TBAATag = 0); + + /// CreateMemMove - Create and insert a memmove between the specified + /// pointers. If the pointers aren't i8*, they will be converted. If a TBAA + /// tag is specified, it will be added to the instruction. + CallInst *CreateMemMove(Value *Dst, Value *Src, uint64_t Size, unsigned Align, + bool isVolatile = false, MDNode *TBAATag = 0) { + return CreateMemMove(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag); + } + + CallInst *CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align, + bool isVolatile = false, MDNode *TBAATag = 0); +private: + Value *getCastedInt8PtrValue(Value *Ptr); }; /// IRBuilder - This provides a uniform API for creating instructions and @@ -279,6 +314,11 @@ SetInsertPoint(TheBB); } + explicit IRBuilder(Instruction *IP) + : IRBuilderBase(IP->getContext()), Folder(Context) { + SetInsertPoint(IP); + } + IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F) : IRBuilderBase(TheBB->getContext()), Folder(F) { SetInsertPoint(TheBB, IP); Modified: llvm/trunk/lib/VMCore/IRBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/IRBuilder.cpp?rev=122571&r1=122570&r2=122571&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/IRBuilder.cpp (original) +++ llvm/trunk/lib/VMCore/IRBuilder.cpp Sun Dec 26 16:49:25 2010 @@ -15,6 +15,7 @@ #include "llvm/Support/IRBuilder.h" #include "llvm/GlobalVariable.h" #include "llvm/Function.h" +#include "llvm/Intrinsics.h" #include "llvm/LLVMContext.h" using namespace llvm; @@ -36,3 +37,83 @@ assert(BB && BB->getParent() && "No current function!"); return BB->getParent()->getReturnType(); } + +Value *IRBuilderBase::getCastedInt8PtrValue(Value *Ptr) { + const PointerType *PT = cast(Ptr->getType()); + if (PT->getElementType()->isIntegerTy(8)) + return Ptr; + + // Otherwise, we need to insert a bitcast. + PT = getInt8PtrTy(PT->getAddressSpace()); + BitCastInst *BCI = new BitCastInst(Ptr, PT, ""); + BB->getInstList().insert(InsertPt, BCI); + SetInstDebugLocation(BCI); + return BCI; +} + +static CallInst *createCallHelper(Value *Callee, Value *const* Ops, + unsigned NumOps, IRBuilderBase *Builder) { + CallInst *CI = CallInst::Create(Callee, Ops, Ops + NumOps, ""); + Builder->GetInsertBlock()->getInstList().insert(Builder->GetInsertPoint(),CI); + Builder->SetInstDebugLocation(CI); + return CI; +} + + +CallInst *IRBuilderBase:: +CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align, + bool isVolatile, MDNode *TBAATag) { + Ptr = getCastedInt8PtrValue(Ptr); + Value *Ops[] = { Ptr, Val, Size, getInt32(Align), getInt1(isVolatile) }; + const Type *Tys[] = { Ptr->getType(), Size->getType() }; + Module *M = BB->getParent()->getParent(); + Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys, 2); + + CallInst *CI = createCallHelper(TheFn, Ops, 5, this); + + // Set the TBAA info if present. + if (TBAATag) + CI->setMetadata(LLVMContext::MD_tbaa, TBAATag); + + return CI; +} + +CallInst *IRBuilderBase:: +CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align, + bool isVolatile, MDNode *TBAATag) { + Dst = getCastedInt8PtrValue(Dst); + Src = getCastedInt8PtrValue(Src); + + Value *Ops[] = { Dst, Src, Size, getInt32(Align), getInt1(isVolatile) }; + const Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() }; + Module *M = BB->getParent()->getParent(); + Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memcpy, Tys, 3); + + CallInst *CI = createCallHelper(TheFn, Ops, 5, this); + + // Set the TBAA info if present. + if (TBAATag) + CI->setMetadata(LLVMContext::MD_tbaa, TBAATag); + + return CI; +} + +CallInst *IRBuilderBase:: +CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align, + bool isVolatile, MDNode *TBAATag) { + Dst = getCastedInt8PtrValue(Dst); + Src = getCastedInt8PtrValue(Src); + + Value *Ops[] = { Dst, Src, Size, getInt32(Align), getInt1(isVolatile) }; + const Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() }; + Module *M = BB->getParent()->getParent(); + Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memmove, Tys, 3); + + CallInst *CI = createCallHelper(TheFn, Ops, 5, this); + + // Set the TBAA info if present. + if (TBAATag) + CI->setMetadata(LLVMContext::MD_tbaa, TBAATag); + + return CI; +} From sabre at nondot.org Sun Dec 26 16:57:42 2010 From: sabre at nondot.org (Chris Lattner) Date: Sun, 26 Dec 2010 22:57:42 -0000 Subject: [llvm-commits] [llvm] r122572 - in /llvm/trunk: lib/Transforms/Scalar/MemCpyOptimizer.cpp lib/Transforms/Scalar/ScalarReplAggregates.cpp test/Transforms/MemCpyOpt/align.ll Message-ID: <20101226225742.2542E2A6C12C@llvm.org> Author: lattner Date: Sun Dec 26 16:57:41 2010 New Revision: 122572 URL: http://llvm.org/viewvc/llvm-project?rev=122572&view=rev Log: start using irbuilder to make mem intrinsics in a few passes. Modified: llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp llvm/trunk/test/Transforms/MemCpyOpt/align.ll Modified: llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp?rev=122572&r1=122571&r2=122572&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Sun Dec 26 16:57:41 2010 @@ -25,6 +25,7 @@ #include "llvm/Analysis/ValueTracking.h" #include "llvm/Support/Debug.h" #include "llvm/Support/GetElementPtrTypeIterator.h" +#include "llvm/Support/IRBuilder.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetData.h" #include @@ -332,8 +333,6 @@ } } - LLVMContext &Context = SI->getContext(); - // There are two cases that are interesting for this code to handle: memcpy // and memset. Right now we only handle memset. @@ -345,7 +344,6 @@ return false; AliasAnalysis &AA = getAnalysis(); - Module *M = SI->getParent()->getParent()->getParent(); // Okay, so we now have a single store that can be splatable. Scan to find // all subsequent stores of the same value to offset from the same pointer. @@ -431,28 +429,10 @@ Alignment = TD->getABITypeAlignment(EltType); } - // Cast the start ptr to be i8* as memset requires. - const PointerType* StartPTy = cast(StartPtr->getType()); - const PointerType *i8Ptr = Type::getInt8PtrTy(Context, - StartPTy->getAddressSpace()); - if (StartPTy!= i8Ptr) - StartPtr = new BitCastInst(StartPtr, i8Ptr, StartPtr->getName(), - InsertPt); - - Value *Ops[] = { - StartPtr, ByteVal, // Start, value - // size - ConstantInt::get(Type::getInt64Ty(Context), Range.End-Range.Start), - // align - ConstantInt::get(Type::getInt32Ty(Context), Alignment), - // volatile - ConstantInt::getFalse(Context), - }; - const Type *Tys[] = { Ops[0]->getType(), Ops[2]->getType() }; - - Function *MemSetF = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys, 2); - - Value *C = CallInst::Create(MemSetF, Ops, Ops+5, "", InsertPt); + IRBuilder<> Builder(InsertPt); + Value *C = + Builder.CreateMemSet(StartPtr, ByteVal, Range.End-Range.Start, Alignment); + DEBUG(dbgs() << "Replace stores:\n"; for (unsigned i = 0, e = Range.TheStores.size(); i != e; ++i) dbgs() << *Range.TheStores[i] << '\n'; @@ -663,20 +643,11 @@ // If the dest of the second might alias the source of the first, then the // source and dest might overlap. We still want to eliminate the intermediate // value, but we have to generate a memmove instead of memcpy. - Intrinsic::ID ResultFn = Intrinsic::memcpy; - if (AA.alias(AA.getLocationForDest(M), AA.getLocationForSource(MDep)) != - AliasAnalysis::NoAlias) - ResultFn = Intrinsic::memmove; + bool UseMemMove = false; + if (!AA.isNoAlias(AA.getLocationForDest(M), AA.getLocationForSource(MDep))) + UseMemMove = true; // If all checks passed, then we can transform M. - const Type *ArgTys[3] = { - M->getRawDest()->getType(), - MDep->getRawSource()->getType(), - M->getLength()->getType() - }; - Function *MemCpyFun = - Intrinsic::getDeclaration(MDep->getParent()->getParent()->getParent(), - ResultFn, ArgTys, 3); // Make sure to use the lesser of the alignment of the source and the dest // since we're changing where we're reading from, but don't want to increase @@ -684,14 +655,14 @@ // TODO: Is this worth it if we're creating a less aligned memcpy? For // example we could be moving from movaps -> movq on x86. unsigned Align = std::min(MDep->getAlignment(), M->getAlignment()); - Value *Args[5] = { - M->getRawDest(), - MDep->getRawSource(), - M->getLength(), - ConstantInt::get(Type::getInt32Ty(MemCpyFun->getContext()), Align), - M->getVolatileCst() - }; - CallInst::Create(MemCpyFun, Args, Args+5, "", M); + + IRBuilder<> Builder(M); + if (UseMemMove) + Builder.CreateMemMove(M->getRawDest(), MDep->getRawSource(), M->getLength(), + Align, M->isVolatile()); + else + Builder.CreateMemCpy(M->getRawDest(), MDep->getRawSource(), M->getLength(), + Align, M->isVolatile()); // Remove the instruction we're replacing. MD->removeInstruction(M); @@ -722,17 +693,9 @@ if (GlobalVariable *GV = dyn_cast(M->getSource())) if (GV->isConstant() && GV->hasDefinitiveInitializer()) if (Value *ByteVal = isBytewiseValue(GV->getInitializer())) { - Value *Ops[] = { - M->getRawDest(), ByteVal, // Start, value - CopySize, // Size - M->getAlignmentCst(), // Alignment - ConstantInt::getFalse(M->getContext()), // volatile - }; - const Type *Tys[] = { Ops[0]->getType(), Ops[2]->getType() }; - Module *Mod = M->getParent()->getParent()->getParent(); - Function *MemSetF = Intrinsic::getDeclaration(Mod, Intrinsic::memset, - Tys, 2); - CallInst::Create(MemSetF, Ops, Ops+5, "", M); + IRBuilder<> Builder(M); + Builder.CreateMemSet(M->getRawDest(), ByteVal, CopySize, + M->getAlignment(), false); MD->removeInstruction(M); M->eraseFromParent(); ++NumCpyToSet; @@ -765,9 +728,7 @@ AliasAnalysis &AA = getAnalysis(); // See if the pointers alias. - if (AA.alias(AA.getLocationForDest(M), - AA.getLocationForSource(M)) != - AliasAnalysis::NoAlias) + if (!AA.isNoAlias(AA.getLocationForDest(M), AA.getLocationForSource(M))) return false; DEBUG(dbgs() << "MemCpyOpt: Optimizing memmove -> memcpy: " << *M << "\n"); Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp?rev=122572&r1=122571&r2=122572&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Sun Dec 26 16:57:41 2010 @@ -425,7 +425,7 @@ continue; } - IRBuilder<> Builder(User->getParent(), User); + IRBuilder<> Builder(User); if (LoadInst *LI = dyn_cast(User)) { // The load is a bit extract from NewAI shifted right by Offset bits. @@ -1353,8 +1353,6 @@ } // Process each element of the aggregate. - Value *TheFn = MI->getCalledValue(); - const Type *BytePtrTy = MI->getRawDest()->getType(); bool SROADest = MI->getRawDest() == Inst; Constant *Zero = Constant::getNullValue(Type::getInt32Ty(MI->getContext())); @@ -1448,55 +1446,24 @@ // Otherwise, if we're storing a byte variable, use a memset call for // this element. } - - // Cast the element pointer to BytePtrTy. - if (EltPtr->getType() != BytePtrTy) - EltPtr = new BitCastInst(EltPtr, BytePtrTy, EltPtr->getName(), MI); - - // Cast the other pointer (if we have one) to BytePtrTy. - if (OtherElt && OtherElt->getType() != BytePtrTy) { - // Preserve address space of OtherElt - const PointerType* OtherPTy = cast(OtherElt->getType()); - const PointerType* PTy = cast(BytePtrTy); - if (OtherPTy->getElementType() != PTy->getElementType()) { - Type *NewOtherPTy = PointerType::get(PTy->getElementType(), - OtherPTy->getAddressSpace()); - OtherElt = new BitCastInst(OtherElt, NewOtherPTy, - OtherElt->getName(), MI); - } - } - + unsigned EltSize = TD->getTypeAllocSize(EltTy); + IRBuilder<> Builder(MI); + // Finally, insert the meminst for this element. - if (isa(MI)) { - Value *Ops[] = { - SROADest ? EltPtr : OtherElt, // Dest ptr - SROADest ? OtherElt : EltPtr, // Src ptr - ConstantInt::get(MI->getArgOperand(2)->getType(), EltSize), // Size - // Align - ConstantInt::get(Type::getInt32Ty(MI->getContext()), OtherEltAlign), - MI->getVolatileCst() - }; - // In case we fold the address space overloaded memcpy of A to B - // with memcpy of B to C, change the function to be a memcpy of A to C. - const Type *Tys[] = { Ops[0]->getType(), Ops[1]->getType(), - Ops[2]->getType() }; - Module *M = MI->getParent()->getParent()->getParent(); - TheFn = Intrinsic::getDeclaration(M, MI->getIntrinsicID(), Tys, 3); - CallInst::Create(TheFn, Ops, Ops + 5, "", MI); + if (isa(MI)) { + Builder.CreateMemSet(EltPtr, MI->getArgOperand(1), EltSize, + MI->isVolatile()); } else { - assert(isa(MI)); - Value *Ops[] = { - EltPtr, MI->getArgOperand(1), // Dest, Value, - ConstantInt::get(MI->getArgOperand(2)->getType(), EltSize), // Size - Zero, // Align - ConstantInt::getFalse(MI->getContext()) // isVolatile - }; - const Type *Tys[] = { Ops[0]->getType(), Ops[2]->getType() }; - Module *M = MI->getParent()->getParent()->getParent(); - TheFn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys, 2); - CallInst::Create(TheFn, Ops, Ops + 5, "", MI); + assert(isa(MI)); + Value *Dst = SROADest ? EltPtr : OtherElt; // Dest ptr + Value *Src = SROADest ? OtherElt : EltPtr; // Src ptr + + if (isa(MI)) + Builder.CreateMemCpy(Dst, Src, EltSize, OtherEltAlign,MI->isVolatile()); + else + Builder.CreateMemMove(Dst, Src, EltSize,OtherEltAlign,MI->isVolatile()); } } DeadInsts.push_back(MI); Modified: llvm/trunk/test/Transforms/MemCpyOpt/align.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/MemCpyOpt/align.ll?rev=122572&r1=122571&r2=122572&view=diff ============================================================================== --- llvm/trunk/test/Transforms/MemCpyOpt/align.ll (original) +++ llvm/trunk/test/Transforms/MemCpyOpt/align.ll Sun Dec 26 16:57:41 2010 @@ -4,7 +4,7 @@ ; The resulting memset is only 4-byte aligned, despite containing ; a 16-byte alignmed store in the middle. -; CHECK: call void @llvm.memset.p0i8.i64(i8* %a01, i8 0, i64 16, i32 4, i1 false) +; CHECK: call void @llvm.memset.p0i8.i64(i8* {{.*}}, i8 0, i64 16, i32 4, i1 false) define void @foo(i32* %p) { %a0 = getelementptr i32* %p, i64 0 From sabre at nondot.org Sun Dec 26 17:42:52 2010 From: sabre at nondot.org (Chris Lattner) Date: Sun, 26 Dec 2010 23:42:52 -0000 Subject: [llvm-commits] [llvm] r122573 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolution.h lib/Transforms/Scalar/LoopIdiomRecognize.cpp test/Transforms/LoopIdiom/ test/Transforms/LoopIdiom/basic.ll test/Transforms/LoopIdiom/dg.exp Message-ID: <20101226234252.20D7F2A6C12C@llvm.org> Author: lattner Date: Sun Dec 26 17:42:51 2010 New Revision: 122573 URL: http://llvm.org/viewvc/llvm-project?rev=122573&view=rev Log: implement enough of the memset inference algorithm to recognize and insert memsets. This is still missing one important validity check, but this is enough to compile stuff like this: void test0(std::vector &X) { for (std::vector::iterator I = X.begin(), E = X.end(); I != E; ++I) *I = 0; } void test1(std::vector &X) { for (long i = 0, e = X.size(); i != e; ++i) X[i] = 0x01010101; } With: $ clang t.cpp -S -o - -O2 -emit-llvm | opt -loop-idiom | opt -O3 | llc to: __Z5test0RSt6vectorIcSaIcEE: ## @_Z5test0RSt6vectorIcSaIcEE ## BB#0: ## %entry subq $8, %rsp movq (%rdi), %rax movq 8(%rdi), %rsi cmpq %rsi, %rax je LBB0_2 ## BB#1: ## %bb.nph subq %rax, %rsi movq %rax, %rdi callq ___bzero LBB0_2: ## %for.end addq $8, %rsp ret ... __Z5test1RSt6vectorIiSaIiEE: ## @_Z5test1RSt6vectorIiSaIiEE ## BB#0: ## %entry subq $8, %rsp movq (%rdi), %rax movq 8(%rdi), %rdx subq %rax, %rdx cmpq $4, %rdx jb LBB1_2 ## BB#1: ## %for.body.preheader andq $-4, %rdx movl $1, %esi movq %rax, %rdi callq _memset LBB1_2: ## %for.end addq $8, %rsp ret Added: llvm/trunk/test/Transforms/LoopIdiom/ llvm/trunk/test/Transforms/LoopIdiom/basic.ll llvm/trunk/test/Transforms/LoopIdiom/dg.exp Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=122573&r1=122572&r2=122573&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original) +++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Sun Dec 26 17:42:51 2010 @@ -539,8 +539,7 @@ /// getMinusSCEV - Return LHS-RHS. /// - const SCEV *getMinusSCEV(const SCEV *LHS, - const SCEV *RHS); + const SCEV *getMinusSCEV(const SCEV *LHS, const SCEV *RHS); /// getTruncateOrZeroExtend - Return a SCEV corresponding to a conversion /// of the input value to the specified type. If the type must be Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=122573&r1=122572&r2=122573&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Sun Dec 26 17:42:51 2010 @@ -17,9 +17,11 @@ #include "llvm/Transforms/Scalar.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h" +#include "llvm/Analysis/ScalarEvolutionExpander.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Target/TargetData.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/IRBuilder.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -41,6 +43,11 @@ bool processLoopStore(StoreInst *SI, const SCEV *BECount); + bool processLoopStoreOfSplatValue(StoreInst *SI, unsigned StoreSize, + Value *SplatValue, + const SCEVAddRecExpr *Ev, + const SCEV *BECount); + /// This transformation requires natural loop information & requires that /// loop preheaders be inserted into the CFG. /// @@ -96,8 +103,11 @@ bool MadeChange = false; for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { // Look for store instructions, which may be memsets. - if (StoreInst *SI = dyn_cast(I++)) - MadeChange |= processLoopStore(SI, BECount); + StoreInst *SI = dyn_cast(I++); + if (SI == 0 || SI->isVolatile()) continue; + + + MadeChange |= processLoopStore(SI, BECount); } return MadeChange; @@ -106,6 +116,7 @@ /// scanBlock - Look over a block to see if we can promote anything out of it. bool LoopIdiomRecognize::processLoopStore(StoreInst *SI, const SCEV *BECount) { Value *StoredVal = SI->getValueOperand(); + Value *StorePtr = SI->getPointerOperand(); // Check to see if the store updates all bits in memory. We don't want to // process things like a store of i3. We also require that the store be a @@ -118,8 +129,7 @@ // See if the pointer expression is an AddRec like {base,+,1} on the current // loop, which indicates a strided store. If we have something else, it's a // random store we can't handle. - const SCEVAddRecExpr *Ev = - dyn_cast(SE->getSCEV(SI->getPointerOperand())); + const SCEVAddRecExpr *Ev = dyn_cast(SE->getSCEV(StorePtr)); if (Ev == 0 || Ev->getLoop() != CurLoop || !Ev->isAffine()) return false; @@ -130,18 +140,75 @@ if (Stride == 0 || StoreSize != Stride->getValue()->getValue()) return false; - errs() << "Found strided store: " << *Ev << "\n"; - - // Check for memcpy here. - - // If the stored value is a byte-wise value (like i32 -1), then it may be // turned into a memset of i8 -1, assuming that all the consequtive bytes // are stored. A store of i32 0x01020304 can never be turned into a memset. - Value *SplatValue = isBytewiseValue(StoredVal); - if (SplatValue == 0) return false; + if (Value *SplatValue = isBytewiseValue(StoredVal)) + return processLoopStoreOfSplatValue(SI, StoreSize, SplatValue, Ev, BECount); + + // Handle the memcpy case here. + errs() << "Found strided store: " << *Ev << "\n"; return false; } +/// processLoopStoreOfSplatValue - We see a strided store of a memsetable value. +/// If we can transform this into a memset in the loop preheader, do so. +bool LoopIdiomRecognize:: +processLoopStoreOfSplatValue(StoreInst *SI, unsigned StoreSize, + Value *SplatValue, + const SCEVAddRecExpr *Ev, const SCEV *BECount) { + // Okay, we have a strided store "p[i]" of a splattable value. We can turn + // this into a memset in the loop preheader now if we want. However, this + // would be unsafe to do if there is anything else in the loop that may read + // or write to the aliased location. Check for an alias. + + // FIXME: TODO safety check. + + // Okay, everything looks good, insert the memset. + BasicBlock *Preheader = CurLoop->getLoopPreheader(); + + IRBuilder<> Builder(Preheader->getTerminator()); + + // The trip count of the loop and the base pointer of the addrec SCEV is + // guaranteed to be loop invariant, which means that it should dominate the + // header. Just insert code for it in the preheader. + SCEVExpander Expander(*SE); + + unsigned AddrSpace = SI->getPointerAddressSpace(); + Value *BasePtr = + Expander.expandCodeFor(Ev->getStart(), Builder.getInt8PtrTy(AddrSpace), + Preheader->getTerminator()); + + // The # stored bytes is (BECount+1)*Size. Expand the trip count out to + // pointer size if it isn't already. + const Type *IntPtr = TD->getIntPtrType(SI->getContext()); + unsigned BESize = SE->getTypeSizeInBits(BECount->getType()); + if (BESize < TD->getPointerSizeInBits()) + BECount = SE->getZeroExtendExpr(BECount, IntPtr); + else if (BESize > TD->getPointerSizeInBits()) + BECount = SE->getTruncateExpr(BECount, IntPtr); + + const SCEV *NumBytesS = SE->getAddExpr(BECount, SE->getConstant(IntPtr, 1), + true, true /*nooverflow*/); + if (StoreSize != 1) + NumBytesS = SE->getMulExpr(NumBytesS, SE->getConstant(IntPtr, StoreSize), + true, true /*nooverflow*/); + + Value *NumBytes = + Expander.expandCodeFor(NumBytesS, IntPtr, Preheader->getTerminator()); + + Value *NewCall = + Builder.CreateMemSet(BasePtr, SplatValue, NumBytes, SI->getAlignment()); + + DEBUG(dbgs() << " Formed memset: " << *NewCall << "\n" + << " from store to: " << *Ev << " at: " << *SI << "\n"); + + // Okay, the memset has been formed. Zap the original store. + // FIXME: We want to recursively delete dead instructions, but we have to + // update SCEV. + SI->eraseFromParent(); + return true; +} + Added: llvm/trunk/test/Transforms/LoopIdiom/basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIdiom/basic.ll?rev=122573&view=auto ============================================================================== --- llvm/trunk/test/Transforms/LoopIdiom/basic.ll (added) +++ llvm/trunk/test/Transforms/LoopIdiom/basic.ll Sun Dec 26 17:42:51 2010 @@ -0,0 +1,44 @@ +; RUN: opt -loop-idiom < %s -S | FileCheck %s +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-apple-darwin10.0.0" + +define void @test1(i8* %Base, i64 %Size) nounwind ssp { +bb.nph: ; preds = %entry + br label %for.body + +for.body: ; preds = %bb.nph, %for.body + %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body ] + %I.0.014 = getelementptr i8* %Base, i64 %indvar + store i8 0, i8* %I.0.014, align 1 + %indvar.next = add i64 %indvar, 1 + %exitcond = icmp eq i64 %indvar.next, %Size + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body, %entry + ret void +; CHECK: @test1 +; CHECK: call void @llvm.memset.p0i8.i64(i8* %Base, i8 0, i64 %Size, i32 1, i1 false) +; CHECK-NOT: store +} + +define void @test2(i32* %Base, i64 %Size) nounwind ssp { +entry: + %cmp10 = icmp eq i64 %Size, 0 + br i1 %cmp10, label %for.end, label %for.body + +for.body: ; preds = %entry, %for.body + %i.011 = phi i64 [ %inc, %for.body ], [ 0, %entry ] + %add.ptr.i = getelementptr i32* %Base, i64 %i.011 + store i32 16843009, i32* %add.ptr.i, align 4 + %inc = add nsw i64 %i.011, 1 + %exitcond = icmp eq i64 %inc, %Size + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body, %entry + ret void +; CHECK: @test2 +; CHECK: br i1 %cmp10, +; CHECK: %tmp = mul i64 %Size, 4 +; CHECK: call void @llvm.memset.p0i8.i64(i8* %Base1, i8 1, i64 %tmp, i32 4, i1 false) +; CHECK-NOT: store +} Added: llvm/trunk/test/Transforms/LoopIdiom/dg.exp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIdiom/dg.exp?rev=122573&view=auto ============================================================================== --- llvm/trunk/test/Transforms/LoopIdiom/dg.exp (added) +++ llvm/trunk/test/Transforms/LoopIdiom/dg.exp Sun Dec 26 17:42:51 2010 @@ -0,0 +1,3 @@ +load_lib llvm.exp + +RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]] From sabre at nondot.org Sun Dec 26 18:03:23 2010 From: sabre at nondot.org (Chris Lattner) Date: Mon, 27 Dec 2010 00:03:23 -0000 Subject: [llvm-commits] [llvm] r122574 - /llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Message-ID: <20101227000323.BB9F62A6C12C@llvm.org> Author: lattner Date: Sun Dec 26 18:03:23 2010 New Revision: 122574 URL: http://llvm.org/viewvc/llvm-project?rev=122574&view=rev Log: have loop-idiom nuke instructions that feed stores that get removed. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=122574&r1=122573&r2=122574&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Sun Dec 26 18:03:23 2010 @@ -20,6 +20,7 @@ #include "llvm/Analysis/ScalarEvolutionExpander.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Target/TargetData.h" +#include "llvm/Transforms/Utils/Local.h" #include "llvm/Support/Debug.h" #include "llvm/Support/IRBuilder.h" #include "llvm/Support/raw_ostream.h" @@ -77,6 +78,40 @@ Pass *llvm::createLoopIdiomPass() { return new LoopIdiomRecognize(); } +/// DeleteDeadInstruction - Delete this instruction. Before we do, go through +/// and zero out all the operands of this instruction. If any of them become +/// dead, delete them and the computation tree that feeds them. +/// +static void DeleteDeadInstruction(Instruction *I, ScalarEvolution &SE) { + SmallVector NowDeadInsts; + + NowDeadInsts.push_back(I); + + // Before we touch this instruction, remove it from SE! + do { + Instruction *DeadInst = NowDeadInsts.pop_back_val(); + + // This instruction is dead, zap it, in stages. Start by removing it from + // SCEV. + SE.forgetValue(DeadInst); + + for (unsigned op = 0, e = DeadInst->getNumOperands(); op != e; ++op) { + Value *Op = DeadInst->getOperand(op); + DeadInst->setOperand(op, 0); + + // If this operand just became dead, add it to the NowDeadInsts list. + if (!Op->use_empty()) continue; + + if (Instruction *OpI = dyn_cast(Op)) + if (isInstructionTriviallyDead(OpI)) + NowDeadInsts.push_back(OpI); + } + + DeadInst->eraseFromParent(); + + } while (!NowDeadInsts.empty()); +} + bool LoopIdiomRecognize::runOnLoop(Loop *L, LPPassManager &LPM) { CurLoop = L; @@ -106,8 +141,13 @@ StoreInst *SI = dyn_cast(I++); if (SI == 0 || SI->isVolatile()) continue; - - MadeChange |= processLoopStore(SI, BECount); + WeakVH InstPtr; + if (processLoopStore(SI, BECount)) { + // If processing the store invalidated our iterator, start over from the + // head of the loop. + if (InstPtr == 0) + I = BB->begin(); + } } return MadeChange; @@ -205,10 +245,9 @@ DEBUG(dbgs() << " Formed memset: " << *NewCall << "\n" << " from store to: " << *Ev << " at: " << *SI << "\n"); - // Okay, the memset has been formed. Zap the original store. - // FIXME: We want to recursively delete dead instructions, but we have to - // update SCEV. - SI->eraseFromParent(); + // Okay, the memset has been formed. Zap the original store and anything that + // feeds into it. + DeleteDeadInstruction(SI, *SE); return true; } From benny.kra at googlemail.com Sun Dec 26 18:16:46 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Mon, 27 Dec 2010 00:16:46 -0000 Subject: [llvm-commits] [llvm] r122575 - /llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp Message-ID: <20101227001646.A24A22A6C12C@llvm.org> Author: d0k Date: Sun Dec 26 18:16:46 2010 New Revision: 122575 URL: http://llvm.org/viewvc/llvm-project?rev=122575&view=rev Log: SimplifyLibCalls: Use IRBuilder to simplify code. Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp?rev=122575&r1=122574&r2=122575&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp Sun Dec 26 18:16:46 2010 @@ -123,7 +123,7 @@ // Verify the "strcat" function prototype. const FunctionType *FT = Callee->getFunctionType(); if (FT->getNumParams() != 2 || - FT->getReturnType() != Type::getInt8PtrTy(*Context) || + FT->getReturnType() != B.getInt8PtrTy() || FT->getParamType(0) != FT->getReturnType() || FT->getParamType(1) != FT->getReturnType()) return 0; @@ -160,9 +160,8 @@ // We have enough information to now generate the memcpy call to do the // concatenation for us. Make a memcpy to copy the nul byte with align = 1. - EmitMemCpy(CpyDst, Src, - ConstantInt::get(TD->getIntPtrType(*Context), Len+1), - 1, false, B, TD); + B.CreateMemCpy(CpyDst, Src, + ConstantInt::get(TD->getIntPtrType(*Context), Len + 1), 1); } }; @@ -174,7 +173,7 @@ // Verify the "strncat" function prototype. const FunctionType *FT = Callee->getFunctionType(); if (FT->getNumParams() != 3 || - FT->getReturnType() != Type::getInt8PtrTy(*Context) || + FT->getReturnType() != B.getInt8PtrTy() || FT->getParamType(0) != FT->getReturnType() || FT->getParamType(1) != FT->getReturnType() || !FT->getParamType(2)->isIntegerTy()) @@ -222,7 +221,7 @@ // Verify the "strchr" function prototype. const FunctionType *FT = Callee->getFunctionType(); if (FT->getNumParams() != 2 || - FT->getReturnType() != Type::getInt8PtrTy(*Context) || + FT->getReturnType() != B.getInt8PtrTy() || FT->getParamType(0) != FT->getReturnType() || !FT->getParamType(1)->isIntegerTy(32)) return 0; @@ -260,8 +259,7 @@ return Constant::getNullValue(CI->getType()); // strchr(s+n,c) -> gep(s+n+i,c) - Value *Idx = ConstantInt::get(Type::getInt64Ty(*Context), I); - return B.CreateGEP(SrcStr, Idx, "strchr"); + return B.CreateGEP(SrcStr, B.getInt64(I), "strchr"); } }; @@ -273,7 +271,7 @@ // Verify the "strrchr" function prototype. const FunctionType *FT = Callee->getFunctionType(); if (FT->getNumParams() != 2 || - FT->getReturnType() != Type::getInt8PtrTy(*Context) || + FT->getReturnType() != B.getInt8PtrTy() || FT->getParamType(0) != FT->getReturnType() || !FT->getParamType(1)->isIntegerTy(32)) return 0; @@ -302,8 +300,7 @@ return Constant::getNullValue(CI->getType()); // strrchr(s+n,c) -> gep(s+n+i,c) - Value *Idx = ConstantInt::get(Type::getInt64Ty(*Context), I); - return B.CreateGEP(SrcStr, Idx, "strrchr"); + return B.CreateGEP(SrcStr, B.getInt64(I), "strrchr"); } }; @@ -317,7 +314,7 @@ if (FT->getNumParams() != 2 || !FT->getReturnType()->isIntegerTy(32) || FT->getParamType(0) != FT->getParamType(1) || - FT->getParamType(0) != Type::getInt8PtrTy(*Context)) + FT->getParamType(0) != B.getInt8PtrTy()) return 0; Value *Str1P = CI->getArgOperand(0), *Str2P = CI->getArgOperand(1); @@ -365,7 +362,7 @@ if (FT->getNumParams() != 3 || !FT->getReturnType()->isIntegerTy(32) || FT->getParamType(0) != FT->getParamType(1) || - FT->getParamType(0) != Type::getInt8PtrTy(*Context) || + FT->getParamType(0) != B.getInt8PtrTy() || !FT->getParamType(2)->isIntegerTy()) return 0; @@ -420,7 +417,7 @@ if (FT->getNumParams() != NumParams || FT->getReturnType() != FT->getParamType(0) || FT->getParamType(0) != FT->getParamType(1) || - FT->getParamType(0) != Type::getInt8PtrTy(*Context)) + FT->getParamType(0) != B.getInt8PtrTy()) return 0; Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1); @@ -441,9 +438,8 @@ ConstantInt::get(TD->getIntPtrType(*Context), Len), CI->getArgOperand(2), B, TD); else - EmitMemCpy(Dst, Src, - ConstantInt::get(TD->getIntPtrType(*Context), Len), - 1, false, B, TD); + B.CreateMemCpy(Dst, Src, + ConstantInt::get(TD->getIntPtrType(*Context), Len), 1); return Dst; } }; @@ -456,7 +452,7 @@ const FunctionType *FT = Callee->getFunctionType(); if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) || FT->getParamType(0) != FT->getParamType(1) || - FT->getParamType(0) != Type::getInt8PtrTy(*Context) || + FT->getParamType(0) != B.getInt8PtrTy() || !FT->getParamType(2)->isIntegerTy()) return 0; @@ -471,8 +467,7 @@ if (SrcLen == 0) { // strncpy(x, "", y) -> memset(x, '\0', y, 1) - EmitMemSet(Dst, ConstantInt::get(Type::getInt8Ty(*Context), '\0'), - LenOp, false, B, TD); + B.CreateMemSet(Dst, B.getInt8('\0'), LenOp, 1); return Dst; } @@ -491,9 +486,8 @@ if (Len > SrcLen+1) return 0; // strncpy(x, s, c) -> memcpy(x, s, c, 1) [s and c are constant] - EmitMemCpy(Dst, Src, - ConstantInt::get(TD->getIntPtrType(*Context), Len), - 1, false, B, TD); + B.CreateMemCpy(Dst, Src, + ConstantInt::get(TD->getIntPtrType(*Context), Len), 1); return Dst; } @@ -506,7 +500,7 @@ virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { const FunctionType *FT = Callee->getFunctionType(); if (FT->getNumParams() != 1 || - FT->getParamType(0) != Type::getInt8PtrTy(*Context) || + FT->getParamType(0) != B.getInt8PtrTy() || !FT->getReturnType()->isIntegerTy()) return 0; @@ -532,7 +526,7 @@ virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { const FunctionType *FT = Callee->getFunctionType(); if (FT->getNumParams() != 2 || - FT->getParamType(0) != Type::getInt8PtrTy(*Context) || + FT->getParamType(0) != B.getInt8PtrTy() || FT->getParamType(1) != FT->getParamType(0) || FT->getReturnType() != FT->getParamType(0)) return 0; @@ -552,8 +546,7 @@ if (I == std::string::npos) // No match. return Constant::getNullValue(CI->getType()); - Value *Idx = ConstantInt::get(Type::getInt64Ty(*Context), I); - return B.CreateGEP(CI->getArgOperand(0), Idx, "strpbrk"); + return B.CreateGEP(CI->getArgOperand(0), B.getInt64(I), "strpbrk"); } // strpbrk(s, "a") -> strchr(s, 'a') @@ -593,7 +586,7 @@ virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { const FunctionType *FT = Callee->getFunctionType(); if (FT->getNumParams() != 2 || - FT->getParamType(0) != Type::getInt8PtrTy(*Context) || + FT->getParamType(0) != B.getInt8PtrTy() || FT->getParamType(1) != FT->getParamType(0) || !FT->getReturnType()->isIntegerTy()) return 0; @@ -622,7 +615,7 @@ virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { const FunctionType *FT = Callee->getFunctionType(); if (FT->getNumParams() != 2 || - FT->getParamType(0) != Type::getInt8PtrTy(*Context) || + FT->getParamType(0) != B.getInt8PtrTy() || FT->getParamType(1) != FT->getParamType(0) || !FT->getReturnType()->isIntegerTy()) return 0; @@ -775,8 +768,8 @@ return 0; // memcpy(x, y, n) -> llvm.memcpy(x, y, n, 1) - EmitMemCpy(CI->getArgOperand(0), CI->getArgOperand(1), - CI->getArgOperand(2), 1, false, B, TD); + B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1), + CI->getArgOperand(2), 1); return CI->getArgOperand(0); } }; @@ -797,8 +790,8 @@ return 0; // memmove(x, y, n) -> llvm.memmove(x, y, n, 1) - EmitMemMove(CI->getArgOperand(0), CI->getArgOperand(1), - CI->getArgOperand(2), 1, false, B, TD); + B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1), + CI->getArgOperand(2), 1); return CI->getArgOperand(0); } }; @@ -819,9 +812,8 @@ return 0; // memset(p, v, n) -> llvm.memset(p, v, n, 1) - Value *Val = B.CreateIntCast(CI->getArgOperand(1), - Type::getInt8Ty(*Context), false); - EmitMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), false, B, TD); + Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), false); + B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1); return CI->getArgOperand(0); } }; @@ -903,12 +895,10 @@ Value *LdExpArg = 0; if (SIToFPInst *OpC = dyn_cast(Op)) { if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() <= 32) - LdExpArg = B.CreateSExt(OpC->getOperand(0), - Type::getInt32Ty(*Context), "tmp"); + LdExpArg = B.CreateSExt(OpC->getOperand(0), B.getInt32Ty(), "tmp"); } else if (UIToFPInst *OpC = dyn_cast(Op)) { if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() < 32) - LdExpArg = B.CreateZExt(OpC->getOperand(0), - Type::getInt32Ty(*Context), "tmp"); + LdExpArg = B.CreateZExt(OpC->getOperand(0), B.getInt32Ty(), "tmp"); } if (LdExpArg) { @@ -927,7 +917,7 @@ Module *M = Caller->getParent(); Value *Callee = M->getOrInsertFunction(Name, Op->getType(), Op->getType(), - Type::getInt32Ty(*Context),NULL); + B.getInt32Ty(), NULL); CallInst *CI = B.CreateCall2(Callee, One, LdExpArg); if (const Function *F = dyn_cast(Callee->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); @@ -957,7 +947,7 @@ Value *V = Cast->getOperand(0); V = EmitUnaryFloatFnCall(V, Callee->getName().data(), B, Callee->getAttributes()); - return B.CreateFPExt(V, Type::getDoubleTy(*Context)); + return B.CreateFPExt(V, B.getDoubleTy()); } }; @@ -984,8 +974,8 @@ if (ConstantInt *CI = dyn_cast(Op)) { if (CI->getValue() == 0) // ffs(0) -> 0. return Constant::getNullValue(CI->getType()); - return ConstantInt::get(Type::getInt32Ty(*Context), // ffs(c) -> cttz(c)+1 - CI->getValue().countTrailingZeros()+1); + // ffs(c) -> cttz(c)+1 + return B.getInt32(CI->getValue().countTrailingZeros() + 1); } // ffs(x) -> x != 0 ? (i32)llvm.cttz(x)+1 : 0 @@ -994,11 +984,10 @@ Intrinsic::cttz, &ArgType, 1); Value *V = B.CreateCall(F, Op, "cttz"); V = B.CreateAdd(V, ConstantInt::get(V->getType(), 1), "tmp"); - V = B.CreateIntCast(V, Type::getInt32Ty(*Context), false, "tmp"); + V = B.CreateIntCast(V, B.getInt32Ty(), false, "tmp"); Value *Cond = B.CreateICmpNE(Op, Constant::getNullValue(ArgType), "tmp"); - return B.CreateSelect(Cond, V, - ConstantInt::get(Type::getInt32Ty(*Context), 0)); + return B.CreateSelect(Cond, V, B.getInt32(0)); } }; @@ -1015,10 +1004,8 @@ // isdigit(c) -> (c-'0') getArgOperand(0); - Op = B.CreateSub(Op, ConstantInt::get(Type::getInt32Ty(*Context), '0'), - "isdigittmp"); - Op = B.CreateICmpULT(Op, ConstantInt::get(Type::getInt32Ty(*Context), 10), - "isdigit"); + Op = B.CreateSub(Op, B.getInt32('0'), "isdigittmp"); + Op = B.CreateICmpULT(Op, B.getInt32(10), "isdigit"); return B.CreateZExt(Op, CI->getType()); } }; @@ -1036,8 +1023,7 @@ // isascii(c) -> c getArgOperand(0); - Op = B.CreateICmpULT(Op, ConstantInt::get(Type::getInt32Ty(*Context), 128), - "isascii"); + Op = B.CreateICmpULT(Op, B.getInt32(128), "isascii"); return B.CreateZExt(Op, CI->getType()); } }; @@ -1055,8 +1041,7 @@ // abs(x) -> x >s -1 ? x : -x Value *Op = CI->getArgOperand(0); - Value *Pos = B.CreateICmpSGT(Op, - Constant::getAllOnesValue(Op->getType()), + Value *Pos = B.CreateICmpSGT(Op, Constant::getAllOnesValue(Op->getType()), "ispos"); Value *Neg = B.CreateNeg(Op, "neg"); return B.CreateSelect(Pos, Op, Neg); @@ -1110,8 +1095,7 @@ // printf("x") -> putchar('x'), even for '%'. Return the result of putchar // in case there is an error writing to stdout. if (FormatStr.size() == 1) { - Value *Res = EmitPutChar(ConstantInt::get(Type::getInt32Ty(*Context), - FormatStr[0]), B, TD); + Value *Res = EmitPutChar(B.getInt32(FormatStr[0]), B, TD); if (CI->use_empty()) return CI; return B.CreateIntCast(Res, CI->getType(), true); } @@ -1180,9 +1164,9 @@ if (!TD) return 0; // sprintf(str, fmt) -> llvm.memcpy(str, fmt, strlen(fmt)+1, 1) - EmitMemCpy(CI->getArgOperand(0), CI->getArgOperand(1), // Copy the - ConstantInt::get(TD->getIntPtrType(*Context), // nul byte. - FormatStr.size() + 1), 1, false, B, TD); + B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1), + ConstantInt::get(TD->getIntPtrType(*Context), // Copy the + FormatStr.size() + 1), 1); // nul byte. return ConstantInt::get(CI->getType(), FormatStr.size()); } @@ -1196,13 +1180,11 @@ if (FormatStr[1] == 'c') { // sprintf(dst, "%c", chr) --> *(i8*)dst = chr; *((i8*)dst+1) = 0 if (!CI->getArgOperand(2)->getType()->isIntegerTy()) return 0; - Value *V = B.CreateTrunc(CI->getArgOperand(2), - Type::getInt8Ty(*Context), "char"); + Value *V = B.CreateTrunc(CI->getArgOperand(2), B.getInt8Ty(), "char"); Value *Ptr = CastToCStr(CI->getArgOperand(0), B); B.CreateStore(V, Ptr); - Ptr = B.CreateGEP(Ptr, ConstantInt::get(Type::getInt32Ty(*Context), 1), - "nul"); - B.CreateStore(Constant::getNullValue(Type::getInt8Ty(*Context)), Ptr); + Ptr = B.CreateGEP(Ptr, B.getInt32(1), "nul"); + B.CreateStore(B.getInt8(0), Ptr); return ConstantInt::get(CI->getType(), 1); } @@ -1218,8 +1200,7 @@ Value *IncLen = B.CreateAdd(Len, ConstantInt::get(Len->getType(), 1), "leninc"); - EmitMemCpy(CI->getArgOperand(0), CI->getArgOperand(2), - IncLen, 1, false, B, TD); + B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(2), IncLen, 1); // The sprintf result is the unincremented number of bytes in the string. return B.CreateIntCast(Len, CI->getType(), false); From benny.kra at googlemail.com Sun Dec 26 18:25:32 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Mon, 27 Dec 2010 00:25:32 -0000 Subject: [llvm-commits] [llvm] r122576 - in /llvm/trunk: include/llvm/Transforms/Utils/BuildLibCalls.h lib/Transforms/Utils/BuildLibCalls.cpp Message-ID: <20101227002532.352D52A6C12C@llvm.org> Author: d0k Date: Sun Dec 26 18:25:32 2010 New Revision: 122576 URL: http://llvm.org/viewvc/llvm-project?rev=122576&view=rev Log: BuildLibCalls: Nuke EmitMemCpy, EmitMemMove and EmitMemSet. They are dead and superseded by IRBuilder. Modified: llvm/trunk/include/llvm/Transforms/Utils/BuildLibCalls.h llvm/trunk/lib/Transforms/Utils/BuildLibCalls.cpp Modified: llvm/trunk/include/llvm/Transforms/Utils/BuildLibCalls.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/BuildLibCalls.h?rev=122576&r1=122575&r2=122576&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/BuildLibCalls.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/BuildLibCalls.h Sun Dec 26 18:25:32 2010 @@ -47,11 +47,6 @@ /// specified pointer arguments and length. Value *EmitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B, const TargetData *TD, StringRef Name = "strncpy"); - - /// EmitMemCpy - Emit a call to the memcpy function to the builder. This - /// always expects that the size has type 'intptr_t' and Dst/Src are pointers. - Value *EmitMemCpy(Value *Dst, Value *Src, Value *Len, unsigned Align, - bool isVolatile, IRBuilder<> &B, const TargetData *TD); /// EmitMemCpyChk - Emit a call to the __memcpy_chk function to the builder. /// This expects that the Len and ObjSize have type 'intptr_t' and Dst/Src @@ -59,11 +54,6 @@ Value *EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize, IRBuilder<> &B, const TargetData *TD); - /// EmitMemMove - Emit a call to the memmove function to the builder. This - /// always expects that the size has type 'intptr_t' and Dst/Src are pointers. - Value *EmitMemMove(Value *Dst, Value *Src, Value *Len, unsigned Align, - bool isVolatile, IRBuilder<> &B, const TargetData *TD); - /// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is /// a pointer, Val is an i32 value, and Len is an 'intptr_t' value. Value *EmitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B, @@ -73,10 +63,6 @@ Value *EmitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, const TargetData *TD); - /// EmitMemSet - Emit a call to the memset function - Value *EmitMemSet(Value *Dst, Value *Val, Value *Len, bool isVolatile, - IRBuilder<> &B, const TargetData *TD); - /// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' /// (e.g. 'floor'). This function is known to take a single of type matching /// 'Op' and returns one value with the same type. If 'Op' is a long double, Modified: llvm/trunk/lib/Transforms/Utils/BuildLibCalls.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BuildLibCalls.cpp?rev=122576&r1=122575&r2=122576&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BuildLibCalls.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BuildLibCalls.cpp Sun Dec 26 18:25:32 2010 @@ -131,21 +131,6 @@ return CI; } - -/// EmitMemCpy - Emit a call to the memcpy function to the builder. This always -/// expects that Len has type 'intptr_t' and Dst/Src are pointers. -Value *llvm::EmitMemCpy(Value *Dst, Value *Src, Value *Len, unsigned Align, - bool isVolatile, IRBuilder<> &B, const TargetData *TD) { - Module *M = B.GetInsertBlock()->getParent()->getParent(); - Dst = CastToCStr(Dst, B); - Src = CastToCStr(Src, B); - const Type *ArgTys[3] = { Dst->getType(), Src->getType(), Len->getType() }; - Value *MemCpy = Intrinsic::getDeclaration(M, Intrinsic::memcpy, ArgTys, 3); - return B.CreateCall5(MemCpy, Dst, Src, Len, - ConstantInt::get(B.getInt32Ty(), Align), - ConstantInt::get(B.getInt1Ty(), isVolatile)); -} - /// EmitMemCpyChk - Emit a call to the __memcpy_chk function to the builder. /// This expects that the Len and ObjSize have type 'intptr_t' and Dst/Src /// are pointers. @@ -170,22 +155,6 @@ return CI; } -/// EmitMemMove - Emit a call to the memmove function to the builder. This -/// always expects that the size has type 'intptr_t' and Dst/Src are pointers. -Value *llvm::EmitMemMove(Value *Dst, Value *Src, Value *Len, unsigned Align, - bool isVolatile, IRBuilder<> &B, const TargetData *TD) { - Module *M = B.GetInsertBlock()->getParent()->getParent(); - LLVMContext &Context = B.GetInsertBlock()->getContext(); - const Type *ArgTys[3] = { Dst->getType(), Src->getType(), - TD->getIntPtrType(Context) }; - Value *MemMove = Intrinsic::getDeclaration(M, Intrinsic::memmove, ArgTys, 3); - Dst = CastToCStr(Dst, B); - Src = CastToCStr(Src, B); - Value *A = ConstantInt::get(B.getInt32Ty(), Align); - Value *Vol = ConstantInt::get(B.getInt1Ty(), isVolatile); - return B.CreateCall5(MemMove, Dst, Src, Len, A, Vol); -} - /// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is /// a pointer, Val is an i32 value, and Len is an 'intptr_t' value. Value *llvm::EmitMemChr(Value *Ptr, Value *Val, @@ -233,18 +202,6 @@ return CI; } -/// EmitMemSet - Emit a call to the memset function -Value *llvm::EmitMemSet(Value *Dst, Value *Val, Value *Len, bool isVolatile, - IRBuilder<> &B, const TargetData *TD) { - Module *M = B.GetInsertBlock()->getParent()->getParent(); - Intrinsic::ID IID = Intrinsic::memset; - const Type *Tys[2] = { Dst->getType(), Len->getType() }; - Value *MemSet = Intrinsic::getDeclaration(M, IID, Tys, 2); - Value *Align = ConstantInt::get(B.getInt32Ty(), 1); - Value *Vol = ConstantInt::get(B.getInt1Ty(), isVolatile); - return B.CreateCall5(MemSet, CastToCStr(Dst, B), Val, Len, Align, Vol); -} - /// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' (e.g. /// 'floor'). This function is known to take a single of type matching 'Op' and /// returns one value with the same type. If 'Op' is a long double, 'l' is @@ -422,8 +379,8 @@ return false; if (isFoldable(3, 2, false)) { - EmitMemCpy(CI->getArgOperand(0), CI->getArgOperand(1), - CI->getArgOperand(2), 1, false, B, TD); + B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1), + CI->getArgOperand(2), 1); replaceCall(CI->getArgOperand(0)); return true; } @@ -445,8 +402,8 @@ return false; if (isFoldable(3, 2, false)) { - EmitMemMove(CI->getArgOperand(0), CI->getArgOperand(1), - CI->getArgOperand(2), 1, false, B, TD); + B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1), + CI->getArgOperand(2), 1); replaceCall(CI->getArgOperand(0)); return true; } @@ -465,8 +422,7 @@ if (isFoldable(3, 2, false)) { Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), false); - EmitMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), - false, B, TD); + B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1); replaceCall(CI->getArgOperand(0)); return true; } From rafael.espindola at gmail.com Sun Dec 26 18:36:05 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Mon, 27 Dec 2010 00:36:05 -0000 Subject: [llvm-commits] [llvm] r122577 - in /llvm/trunk: include/llvm/MC/MCDwarf.h include/llvm/MC/MCFixup.h include/llvm/MC/MCStreamer.h lib/MC/ELFObjectWriter.cpp lib/MC/MCAsmStreamer.cpp lib/MC/MCDwarf.cpp lib/MC/MCParser/AsmParser.cpp lib/MC/MCStreamer.cpp lib/MC/TargetAsmBackend.cpp lib/Target/X86/X86AsmBackend.cpp test/MC/ELF/cfi.s Message-ID: <20101227003605.E03012A6C12C@llvm.org> Author: rafael Date: Sun Dec 26 18:36:05 2010 New Revision: 122577 URL: http://llvm.org/viewvc/llvm-project?rev=122577&view=rev Log: Add support for the same encodings of the personality function that gnu as supports. Modified: llvm/trunk/include/llvm/MC/MCDwarf.h llvm/trunk/include/llvm/MC/MCFixup.h llvm/trunk/include/llvm/MC/MCStreamer.h llvm/trunk/lib/MC/ELFObjectWriter.cpp llvm/trunk/lib/MC/MCAsmStreamer.cpp llvm/trunk/lib/MC/MCDwarf.cpp llvm/trunk/lib/MC/MCParser/AsmParser.cpp llvm/trunk/lib/MC/MCStreamer.cpp llvm/trunk/lib/MC/TargetAsmBackend.cpp llvm/trunk/lib/Target/X86/X86AsmBackend.cpp llvm/trunk/test/MC/ELF/cfi.s Modified: llvm/trunk/include/llvm/MC/MCDwarf.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCDwarf.h?rev=122577&r1=122576&r2=122577&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCDwarf.h (original) +++ llvm/trunk/include/llvm/MC/MCDwarf.h Sun Dec 26 18:36:05 2010 @@ -231,6 +231,7 @@ MCSymbol *End; const MCSymbol *Personality; const MCSymbol *Lsda; + unsigned PersonalityEncoding; }; class MCDwarfFrameEmitter { Modified: llvm/trunk/include/llvm/MC/MCFixup.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCFixup.h?rev=122577&r1=122576&r2=122577&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCFixup.h (original) +++ llvm/trunk/include/llvm/MC/MCFixup.h Sun Dec 26 18:36:05 2010 @@ -25,6 +25,7 @@ FK_PCRel_1, ///< A one-byte pc relative fixup. FK_PCRel_2, ///< A two-byte pc relative fixup. FK_PCRel_4, ///< A four-byte pc relative fixup. + FK_PCRel_8, ///< A eight-byte pc relative fixup. FirstTargetFixupKind = 128, @@ -86,9 +87,7 @@ case 1: return isPCRel ? FK_PCRel_1 : FK_Data_1; case 2: return isPCRel ? FK_PCRel_2 : FK_Data_2; case 4: return isPCRel ? FK_PCRel_4 : FK_Data_4; - case 8: - assert(!isPCRel && "8 byte pc relative fixup is not supported."); - return FK_Data_8; + case 8: return isPCRel ? FK_PCRel_8 : FK_Data_8; } } }; Modified: llvm/trunk/include/llvm/MC/MCStreamer.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=122577&r1=122576&r2=122577&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCStreamer.h (original) +++ llvm/trunk/include/llvm/MC/MCStreamer.h Sun Dec 26 18:36:05 2010 @@ -394,7 +394,8 @@ virtual bool EmitCFIDefCfaOffset(int64_t Offset); virtual bool EmitCFIDefCfaRegister(int64_t Register); virtual bool EmitCFIOffset(int64_t Register, int64_t Offset); - virtual bool EmitCFIPersonality(const MCSymbol *Sym); + virtual bool EmitCFIPersonality(const MCSymbol *Sym, + unsigned Encoding); virtual bool EmitCFILsda(const MCSymbol *Sym); /// EmitInstruction - Emit the given @p Instruction into the current Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=122577&r1=122576&r2=122577&view=diff ============================================================================== --- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Sun Dec 26 18:36:05 2010 @@ -1604,26 +1604,41 @@ unsigned Type; if (is64Bit()) { if (IsPCRel) { - switch (Modifier) { - default: - llvm_unreachable("Unimplemented"); - case MCSymbolRefExpr::VK_None: - Type = ELF::R_X86_64_PC32; - break; - case MCSymbolRefExpr::VK_PLT: - Type = ELF::R_X86_64_PLT32; - break; - case MCSymbolRefExpr::VK_GOTPCREL: - Type = ELF::R_X86_64_GOTPCREL; + switch ((unsigned)Fixup.getKind()) { + default: llvm_unreachable("invalid fixup kind!"); + case FK_PCRel_8: + assert(Modifier == MCSymbolRefExpr::VK_None); + Type = ELF::R_X86_64_PC64; break; - case MCSymbolRefExpr::VK_GOTTPOFF: - Type = ELF::R_X86_64_GOTTPOFF; + case FK_Data_4: // FIXME? + case X86::reloc_riprel_4byte: + case FK_PCRel_4: + switch (Modifier) { + default: + llvm_unreachable("Unimplemented"); + case MCSymbolRefExpr::VK_None: + Type = ELF::R_X86_64_PC32; + break; + case MCSymbolRefExpr::VK_PLT: + Type = ELF::R_X86_64_PLT32; + break; + case MCSymbolRefExpr::VK_GOTPCREL: + Type = ELF::R_X86_64_GOTPCREL; + break; + case MCSymbolRefExpr::VK_GOTTPOFF: + Type = ELF::R_X86_64_GOTTPOFF; break; - case MCSymbolRefExpr::VK_TLSGD: - Type = ELF::R_X86_64_TLSGD; + case MCSymbolRefExpr::VK_TLSGD: + Type = ELF::R_X86_64_TLSGD; + break; + case MCSymbolRefExpr::VK_TLSLD: + Type = ELF::R_X86_64_TLSLD; + break; + } break; - case MCSymbolRefExpr::VK_TLSLD: - Type = ELF::R_X86_64_TLSLD; + case FK_PCRel_2: + assert(Modifier == MCSymbolRefExpr::VK_None); + Type = ELF::R_X86_64_PC16; break; } } else { @@ -1631,7 +1646,6 @@ default: llvm_unreachable("invalid fixup kind!"); case FK_Data_8: Type = ELF::R_X86_64_64; break; case X86::reloc_signed_4byte: - case FK_PCRel_4: assert(isInt<32>(Target.getConstant())); switch (Modifier) { default: Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=122577&r1=122576&r2=122577&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Sun Dec 26 18:36:05 2010 @@ -189,7 +189,7 @@ virtual bool EmitCFIDefCfaOffset(int64_t Offset); virtual bool EmitCFIDefCfaRegister(int64_t Register); virtual bool EmitCFIOffset(int64_t Register, int64_t Offset); - virtual bool EmitCFIPersonality(const MCSymbol *Sym); + virtual bool EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding); virtual bool EmitCFILsda(const MCSymbol *Sym); virtual void EmitInstruction(const MCInst &Inst); @@ -758,11 +758,12 @@ return false; } -bool MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym) { - if (this->MCStreamer::EmitCFIPersonality(Sym)) +bool MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym, + unsigned Encoding) { + if (this->MCStreamer::EmitCFIPersonality(Sym, Encoding)) return true; - OS << ".cfi_personality 0, " << *Sym; + OS << ".cfi_personality " << Encoding << ", " << *Sym; EmitEOL(); return false; Modified: llvm/trunk/lib/MC/MCDwarf.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf.cpp?rev=122577&r1=122576&r2=122577&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCDwarf.cpp (original) +++ llvm/trunk/lib/MC/MCDwarf.cpp Sun Dec 26 18:36:05 2010 @@ -509,7 +509,8 @@ } static const MCSymbol &EmitCIE(MCStreamer &streamer, - const MCSymbol *personality) { + const MCSymbol *personality, + unsigned personalityEncoding) { MCContext &context = streamer.getContext(); const TargetAsmInfo &asmInfo = context.getTargetAsmInfo(); const MCSection §ion = *asmInfo.getEHFrameSection(); @@ -559,9 +560,44 @@ streamer.EmitLabel(augmentationStart); if (personality) { // Personality Encoding - streamer.EmitIntValue(dwarf::DW_EH_PE_absptr, 1); + streamer.EmitIntValue(personalityEncoding, 1); // Personality - streamer.EmitSymbolValue(personality, asmInfo.getPointerSize()); + unsigned format = personalityEncoding & 0x0f; + unsigned application = personalityEncoding & 0xf0; + unsigned size; + switch (format) { + default: + assert(0 && "Unknown Encoding"); + break; + case dwarf::DW_EH_PE_absptr: + case dwarf::DW_EH_PE_signed: + size = asmInfo.getPointerSize(); + break; + case dwarf::DW_EH_PE_udata2: + case dwarf::DW_EH_PE_sdata2: + size = 2; + break; + case dwarf::DW_EH_PE_udata4: + case dwarf::DW_EH_PE_sdata4: + size = 4; + break; + case dwarf::DW_EH_PE_udata8: + case dwarf::DW_EH_PE_sdata8: + size = 8; + break; + } + switch (application) { + default: + assert(0 && "Unknown Encoding"); + break; + case 0: + case dwarf::DW_EH_PE_indirect: + streamer.EmitSymbolValue(personality, size); + break; + case dwarf::DW_EH_PE_pcrel: + streamer.EmitPCRelSymbolValue(personality, size); + break; + } } // Encoding of the FDE pointers streamer.EmitIntValue(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4, 1); @@ -620,13 +656,16 @@ const MCContext &context = streamer.getContext(); const TargetAsmInfo &asmInfo = context.getTargetAsmInfo(); MCSymbol *fdeEnd = NULL; - DenseMap Personalities; + typedef std::pair personalityKey; + DenseMap personalities; for (unsigned i = 0, n = streamer.getNumFrameInfos(); i < n; ++i) { const MCDwarfFrameInfo &frame = streamer.getFrameInfo(i); - const MCSymbol *&cieStart = Personalities[frame.Personality]; + personalityKey key(frame.Personality, frame.PersonalityEncoding); + const MCSymbol *&cieStart = personalities[key]; if (!cieStart) - cieStart = &EmitCIE(streamer, frame.Personality); + cieStart = &EmitCIE(streamer, frame.Personality, + frame.PersonalityEncoding); fdeEnd = EmitFDE(streamer, *cieStart, frame); if (i != n - 1) streamer.EmitLabel(fdeEnd); Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=122577&r1=122576&r2=122577&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original) +++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Sun Dec 26 18:36:05 2010 @@ -2254,7 +2254,7 @@ MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); if (IDVal == ".cfi_personality") - return getStreamer().EmitCFIPersonality(Sym); + return getStreamer().EmitCFIPersonality(Sym, Encoding); else { assert(IDVal == ".cfi_lsda"); return getStreamer().EmitCFILsda(Sym); Modified: llvm/trunk/lib/MC/MCStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=122577&r1=122576&r2=122577&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCStreamer.cpp Sun Dec 26 18:36:05 2010 @@ -187,10 +187,12 @@ return false; } -bool MCStreamer::EmitCFIPersonality(const MCSymbol *Sym) { +bool MCStreamer::EmitCFIPersonality(const MCSymbol *Sym, + unsigned Encoding) { EnsureValidFrame(); MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); CurFrame->Personality = Sym; + CurFrame->PersonalityEncoding = Encoding; return false; } Modified: llvm/trunk/lib/MC/TargetAsmBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/TargetAsmBackend.cpp?rev=122577&r1=122576&r2=122577&view=diff ============================================================================== --- llvm/trunk/lib/MC/TargetAsmBackend.cpp (original) +++ llvm/trunk/lib/MC/TargetAsmBackend.cpp Sun Dec 26 18:36:05 2010 @@ -27,7 +27,8 @@ { "FK_Data_8", 0, 64, 0 }, { "FK_PCRel_1", 0, 8, MCFixupKindInfo::FKF_IsPCRel }, { "FK_PCRel_2", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, - { "FK_PCRel_4", 0, 32, MCFixupKindInfo::FKF_IsPCRel } + { "FK_PCRel_4", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, + { "FK_PCRel_8", 0, 64, MCFixupKindInfo::FKF_IsPCRel } }; assert(Kind <= sizeof(Builtins) / sizeof(Builtins[0]) && Modified: llvm/trunk/lib/Target/X86/X86AsmBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86AsmBackend.cpp?rev=122577&r1=122576&r2=122577&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86AsmBackend.cpp (original) +++ llvm/trunk/lib/Target/X86/X86AsmBackend.cpp Sun Dec 26 18:36:05 2010 @@ -41,6 +41,7 @@ case X86::reloc_signed_4byte: case X86::reloc_global_offset_table: case FK_Data_4: return 2; + case FK_PCRel_8: case FK_Data_8: return 3; } } Modified: llvm/trunk/test/MC/ELF/cfi.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/cfi.s?rev=122577&r1=122576&r2=122577&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/cfi.s (original) +++ llvm/trunk/test/MC/ELF/cfi.s Sun Dec 26 18:36:05 2010 @@ -22,27 +22,164 @@ nop .cfi_endproc +f5: + .cfi_startproc + .cfi_personality 0x02, foo + nop + .cfi_endproc + +f6: + .cfi_startproc + .cfi_personality 0x03, foo + nop + .cfi_endproc + +f7: + .cfi_startproc + .cfi_personality 0x04, foo + nop + .cfi_endproc + +f8: + .cfi_startproc + .cfi_personality 0x0a, foo + nop + .cfi_endproc + +f9: + .cfi_startproc + .cfi_personality 0x0b, foo + nop + .cfi_endproc + +f10: + .cfi_startproc + .cfi_personality 0x0c, foo + nop + .cfi_endproc + +f11: + .cfi_startproc + .cfi_personality 0x08, foo + nop + .cfi_endproc + +f12: + .cfi_startproc + .cfi_personality 0x10, foo + nop + .cfi_endproc + +f13: + .cfi_startproc + .cfi_personality 0x12, foo + nop + .cfi_endproc + +f14: + .cfi_startproc + .cfi_personality 0x13, foo + nop + .cfi_endproc + +f15: + .cfi_startproc + .cfi_personality 0x14, foo + nop + .cfi_endproc + +f16: + .cfi_startproc + .cfi_personality 0x1a, foo + nop + .cfi_endproc + +f17: + .cfi_startproc + .cfi_personality 0x1b, foo + nop + .cfi_endproc + +f18: + .cfi_startproc + .cfi_personality 0x1c, foo + nop + .cfi_endproc + +f19: + .cfi_startproc + .cfi_personality 0x18, foo + nop + .cfi_endproc + +f20: + .cfi_startproc + .cfi_personality 0x80, foo + nop + .cfi_endproc + +f21: + .cfi_startproc + .cfi_personality 0x82, foo + nop + .cfi_endproc + +f22: + .cfi_startproc + .cfi_personality 0x83, foo + nop + .cfi_endproc + +f23: + .cfi_startproc + .cfi_personality 0x84, foo + nop + .cfi_endproc + +f24: + .cfi_startproc + .cfi_personality 0x8a, foo + nop + .cfi_endproc + +f25: + .cfi_startproc + .cfi_personality 0x8b, foo + nop + .cfi_endproc + +f26: + .cfi_startproc + .cfi_personality 0x8c, foo + nop + .cfi_endproc + +f27: + .cfi_startproc + .cfi_personality 0x88, foo + nop + .cfi_endproc // CHECK: # Section 0x00000004 // CHECK-NEXT: (('sh_name', 0x00000012) # '.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000001) // CHECK-NEXT: ('sh_flags', 0x00000002) // CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000048) -// CHECK-NEXT: ('sh_size', 0x00000088) +// CHECK-NEXT: ('sh_offset', 0x00000060) +// CHECK-NEXT: ('sh_size', 0x00000508) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) // CHECK-NEXT: ('sh_addralign', 0x00000008) // CHECK-NEXT: ('sh_entsize', 0x00000000) -// CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 10000000 1c000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a000000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 10000000 64000000 00000000 01000000 00000000 10000000 4c000000 00000000 01000000 00000000') +// CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 10000000 1c000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a000000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 10000000 64000000 00000000 01000000 00000000 10000000 4c000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 04020000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 06030000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a040000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 040a0000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 060b0000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a0c0000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a080000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a100000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 04120000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 06130000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a140000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 041a0000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 061b0000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a1c0000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a180000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a800000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 04820000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 06830000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a840000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 048a0000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 068b0000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a8c0000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a880000 00000000 00001b0c 07089001 14000000 24000000 00000000 01000000 00000000 00000000') // CHECK-NEXT: ), -// CHECK: # Section 0x00000008 +// CHECK: # Section 0x00000008 // CHECK-NEXT: (('sh_name', 0x00000036) # '.rela.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000004) // CHECK-NEXT: ('sh_flags', 0x00000000) // CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000220) -// CHECK-NEXT: ('sh_size', 0x00000078) +// CHECK-NEXT: ('sh_offset', 0x00000930) +// CHECK-NEXT: ('sh_size', 0x000004c8) // CHECK-NEXT: ('sh_link', 0x00000006) // CHECK-NEXT: ('sh_info', 0x00000004) // CHECK-NEXT: ('sh_addralign', 0x00000008) @@ -50,33 +187,309 @@ // CHECK-NEXT: ('_relocations', [ // CHECK-NEXT: # Relocation 0x00000000 // CHECK-NEXT: (('r_offset', 0x00000020) -// CHECK-NEXT: ('r_sym', 0x00000005) +// CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000001 // CHECK-NEXT: (('r_offset', 0x0000003e) -// CHECK-NEXT: ('r_sym', 0x00000009) +// CHECK-NEXT: ('r_sym', 0x00000020) // CHECK-NEXT: ('r_type', 0x00000001) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000002 // CHECK-NEXT: (('r_offset', 0x00000054) -// CHECK-NEXT: ('r_sym', 0x00000005) +// CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000001) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000003 // CHECK-NEXT: (('r_offset', 0x00000068) -// CHECK-NEXT: ('r_sym', 0x00000005) +// CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000002) // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000004 // CHECK-NEXT: (('r_offset', 0x0000007c) -// CHECK-NEXT: ('r_sym', 0x00000005) +// CHECK-NEXT: ('r_sym', 0x0000001c) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x00000003) // CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000005 +// CHECK-NEXT: (('r_offset', 0x0000009a) +// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_type', 0x0000000c) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000006 +// CHECK-NEXT: (('r_offset', 0x000000ac) +// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000004) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000007 +// CHECK-NEXT: (('r_offset', 0x000000ca) +// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_type', 0x0000000a) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000008 +// CHECK-NEXT: (('r_offset', 0x000000dc) +// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000005) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000009 +// CHECK-NEXT: (('r_offset', 0x000000fa) +// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_type', 0x00000001) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x0000000a +// CHECK-NEXT: (('r_offset', 0x00000110) +// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000006) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x0000000b +// CHECK-NEXT: (('r_offset', 0x0000012e) +// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_type', 0x0000000c) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x0000000c +// CHECK-NEXT: (('r_offset', 0x00000140) +// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000007) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x0000000d +// CHECK-NEXT: (('r_offset', 0x0000015e) +// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_type', 0x0000000a) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x0000000e +// CHECK-NEXT: (('r_offset', 0x00000170) +// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000008) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x0000000f +// CHECK-NEXT: (('r_offset', 0x0000018e) +// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_type', 0x00000001) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000010 +// CHECK-NEXT: (('r_offset', 0x000001a4) +// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000009) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000011 +// CHECK-NEXT: (('r_offset', 0x000001c2) +// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_type', 0x00000001) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000012 +// CHECK-NEXT: (('r_offset', 0x000001d8) +// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x0000000a) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000013 +// CHECK-NEXT: (('r_offset', 0x000001f6) +// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_type', 0x00000018) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000014 +// CHECK-NEXT: (('r_offset', 0x0000020c) +// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x0000000b) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000015 +// CHECK-NEXT: (('r_offset', 0x0000022a) +// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_type', 0x0000000d) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000016 +// CHECK-NEXT: (('r_offset', 0x0000023c) +// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x0000000c) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000017 +// CHECK-NEXT: (('r_offset', 0x0000025a) +// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000018 +// CHECK-NEXT: (('r_offset', 0x0000026c) +// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x0000000d) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000019 +// CHECK-NEXT: (('r_offset', 0x0000028a) +// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_type', 0x00000018) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x0000001a +// CHECK-NEXT: (('r_offset', 0x000002a0) +// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x0000000e) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x0000001b +// CHECK-NEXT: (('r_offset', 0x000002be) +// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_type', 0x0000000d) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x0000001c +// CHECK-NEXT: (('r_offset', 0x000002d0) +// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x0000000f) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x0000001d +// CHECK-NEXT: (('r_offset', 0x000002ee) +// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x0000001e +// CHECK-NEXT: (('r_offset', 0x00000300) +// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000010) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x0000001f +// CHECK-NEXT: (('r_offset', 0x0000031e) +// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_type', 0x00000018) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000020 +// CHECK-NEXT: (('r_offset', 0x00000334) +// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000011) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000021 +// CHECK-NEXT: (('r_offset', 0x00000352) +// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_type', 0x00000018) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000022 +// CHECK-NEXT: (('r_offset', 0x00000368) +// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000012) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000023 +// CHECK-NEXT: (('r_offset', 0x00000386) +// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_type', 0x00000001) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000024 +// CHECK-NEXT: (('r_offset', 0x0000039c) +// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000013) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000025 +// CHECK-NEXT: (('r_offset', 0x000003ba) +// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_type', 0x0000000c) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000026 +// CHECK-NEXT: (('r_offset', 0x000003cc) +// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000014) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000027 +// CHECK-NEXT: (('r_offset', 0x000003ea) +// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_type', 0x0000000a) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000028 +// CHECK-NEXT: (('r_offset', 0x000003fc) +// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000015) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000029 +// CHECK-NEXT: (('r_offset', 0x0000041a) +// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_type', 0x00000001) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x0000002a +// CHECK-NEXT: (('r_offset', 0x00000430) +// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000016) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x0000002b +// CHECK-NEXT: (('r_offset', 0x0000044e) +// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_type', 0x0000000c) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x0000002c +// CHECK-NEXT: (('r_offset', 0x00000460) +// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000017) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x0000002d +// CHECK-NEXT: (('r_offset', 0x0000047e) +// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_type', 0x0000000a) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x0000002e +// CHECK-NEXT: (('r_offset', 0x00000490) +// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000018) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x0000002f +// CHECK-NEXT: (('r_offset', 0x000004ae) +// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_type', 0x00000001) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000030 +// CHECK-NEXT: (('r_offset', 0x000004c4) +// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000019) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000031 +// CHECK-NEXT: (('r_offset', 0x000004e2) +// CHECK-NEXT: ('r_sym', 0x00000020) +// CHECK-NEXT: ('r_type', 0x00000001) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000032 +// CHECK-NEXT: (('r_offset', 0x000004f8) +// CHECK-NEXT: ('r_sym', 0x0000001c) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x0000001a) +// CHECK-NEXT: ), // CHECK-NEXT: ]) // CHECK-NEXT: ), From geek4civic at gmail.com Sun Dec 26 19:31:41 2010 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Mon, 27 Dec 2010 10:31:41 +0900 Subject: [llvm-commits] [PATCH] Add some options to configure for Cygming In-Reply-To: References: Message-ID: Ping. Regenerated patches attached. * 0001-autoconf-PR7874-Add-disable-pthreads-to-suppress.patch.txt --enable-pthreads=yes by default. It would be needed to build pthread*.dll-free binaries on mingw. Without this patch, it would be impossible to build with ENABLE_THREADS=1 without pthread.h and pthread*.dll, [PR7874] * 0003-autoconf-Add-disable-embed-stdcxx-to-suppress-li.patch.txt --enable-embed-stdcxx=yes by default. Use with --enable-shared. By default, tools/llvm-shlib does not use stdc++.dll but link stdc++.a included into llvm*.dll. Cygwin-1.7's gcc-4.4 has its own stdc++.dll and is applicable. With --disable-embed-stdcxx, tools/llvm-shlib uses distro's stdc++.dll. * 0002-configure-Regenerated-for-disable-pthreads.patch.txt * 0004-configure-Regenerated-for-disable-embed-stdcxx.patch.txt Regenerated patches. ...Takumi -------------- next part -------------- From e30a31becf1be7c565d41390a5aa5a05bcec2b21 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 10 Nov 2010 12:05:35 +0900 Subject: [PATCH 1/4] autoconf: [PR7874] Add --disable-pthreads to suppress detecting pthreads on certain hosts. This would be needed to build pthread*.dll-free distribution on recent MinGW-MSYS distros. --- autoconf/configure.ac | 16 ++++++++++++++-- 1 files changed, 14 insertions(+), 2 deletions(-) diff --git a/autoconf/configure.ac b/autoconf/configure.ac index eca0ae4..93a31c8 100644 --- a/autoconf/configure.ac +++ b/autoconf/configure.ac @@ -530,6 +530,18 @@ case "$enableval" in esac AC_DEFINE_UNQUOTED([ENABLE_THREADS],$ENABLE_THREADS,[Define if threads enabled]) +dnl Allow disablement of pthread.h +AC_ARG_ENABLE(pthreads, + AS_HELP_STRING([--enable-pthreads], + [Use pthreads if available (default is YES)]),, + enableval=default) +case "$enableval" in + yes) AC_SUBST(ENABLE_PTHREADS,[1]) ;; + no) AC_SUBST(ENABLE_PTHREADS,[0]) ;; + default) AC_SUBST(ENABLE_PTHREADS,[1]) ;; + *) AC_MSG_ERROR([Invalid setting for --enable-pthreads. Use "yes" or "no"]) ;; +esac + dnl Allow building without position independent code AC_ARG_ENABLE(pic, AS_HELP_STRING([--enable-pic], @@ -1216,7 +1228,7 @@ AC_SEARCH_LIBS(mallinfo,malloc,AC_DEFINE([HAVE_MALLINFO],[1], dnl pthread locking functions are optional - but llvm will not be thread-safe dnl without locks. -if test "$ENABLE_THREADS" -eq 1 ; then +if test "$ENABLE_THREADS" -eq 1 && test "$ENABLE_PTHREADS" -eq 1 ; then AC_CHECK_LIB(pthread, pthread_mutex_init) AC_SEARCH_LIBS(pthread_mutex_lock,pthread, AC_DEFINE([HAVE_PTHREAD_MUTEX_LOCK],[1], @@ -1308,7 +1320,7 @@ AC_CHECK_HEADERS([sys/mman.h sys/param.h sys/resource.h sys/time.h]) AC_CHECK_HEADERS([sys/types.h sys/ioctl.h malloc/malloc.h mach/mach.h]) AC_CHECK_HEADERS([valgrind/valgrind.h]) AC_CHECK_HEADERS([fenv.h]) -if test "$ENABLE_THREADS" -eq 1 ; then +if test "$ENABLE_THREADS" -eq 1 && test "$ENABLE_PTHREADS" -eq 1 ; then AC_CHECK_HEADERS(pthread.h, AC_SUBST(HAVE_PTHREAD, 1), AC_SUBST(HAVE_PTHREAD, 0)) -- 1.7.1.GIT -------------- next part -------------- From 6e095dc62552b9c184017f99f3473ea54dab3416 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 10 Nov 2010 12:06:32 +0900 Subject: [PATCH 2/4] configure: Regenerated for --disable-pthreads. --- configure | 34 ++++++++++++++++++++++++++++------ 1 files changed, 28 insertions(+), 6 deletions(-) diff --git a/configure b/configure index be9fd70..ac24889 100755 --- a/configure +++ b/configure @@ -691,6 +691,7 @@ TARGET_HAS_JIT ENABLE_DOCS ENABLE_DOXYGEN ENABLE_THREADS +ENABLE_PTHREADS ENABLE_PIC ENABLE_SHARED ENABLE_TIMESTAMPS @@ -1415,6 +1416,7 @@ Optional Features: --enable-docs Build documents (default is YES) --enable-doxygen Build doxygen documentation (default is NO) --enable-threads Use threads if available (default is YES) + --enable-pthreads Use pthreads if available (default is YES) --enable-pic Build LLVM with Position Independent Code (default is YES) --enable-shared Build a shared library and link tools against it @@ -4935,6 +4937,25 @@ cat >>confdefs.h <<_ACEOF _ACEOF +# Check whether --enable-pthreads was given. +if test "${enable_pthreads+set}" = set; then + enableval=$enable_pthreads; +else + enableval=default +fi + +case "$enableval" in + yes) ENABLE_PTHREADS=1 + ;; + no) ENABLE_PTHREADS=0 + ;; + default) ENABLE_PTHREADS=1 + ;; + *) { { echo "$as_me:$LINENO: error: Invalid setting for --enable-pthreads. Use \"yes\" or \"no\"" >&5 +echo "$as_me: error: Invalid setting for --enable-pthreads. Use \"yes\" or \"no\"" >&2;} + { (exit 1); exit 1; }; } ;; +esac + # Check whether --enable-pic was given. if test "${enable_pic+set}" = set; then enableval=$enable_pic; @@ -11518,7 +11539,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <&5 echo $ECHO_N "checking for pthread_mutex_init in -lpthread... $ECHO_C" >&6; } @@ -16897,7 +16918,7 @@ fi done -if test "$ENABLE_THREADS" -eq 1 ; then +if test "$ENABLE_THREADS" -eq 1 && test "$ENABLE_PTHREADS" -eq 1 ; then for ac_header in pthread.h do @@ -21788,6 +21809,7 @@ TARGET_HAS_JIT!$TARGET_HAS_JIT$ac_delim ENABLE_DOCS!$ENABLE_DOCS$ac_delim ENABLE_DOXYGEN!$ENABLE_DOXYGEN$ac_delim ENABLE_THREADS!$ENABLE_THREADS$ac_delim +ENABLE_PTHREADS!$ENABLE_PTHREADS$ac_delim ENABLE_PIC!$ENABLE_PIC$ac_delim ENABLE_SHARED!$ENABLE_SHARED$ac_delim ENABLE_TIMESTAMPS!$ENABLE_TIMESTAMPS$ac_delim @@ -21795,7 +21817,6 @@ TARGETS_TO_BUILD!$TARGETS_TO_BUILD$ac_delim LLVM_ENUM_TARGETS!$LLVM_ENUM_TARGETS$ac_delim LLVM_ENUM_ASM_PRINTERS!$LLVM_ENUM_ASM_PRINTERS$ac_delim LLVM_ENUM_ASM_PARSERS!$LLVM_ENUM_ASM_PARSERS$ac_delim -LLVM_ENUM_DISASSEMBLERS!$LLVM_ENUM_DISASSEMBLERS$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then @@ -21837,6 +21858,7 @@ _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF +LLVM_ENUM_DISASSEMBLERS!$LLVM_ENUM_DISASSEMBLERS$ac_delim ENABLE_CBE_PRINTF_A!$ENABLE_CBE_PRINTF_A$ac_delim CLANGPATH!$CLANGPATH$ac_delim CLANGXXPATH!$CLANGXXPATH$ac_delim @@ -21933,7 +21955,6 @@ BINDINGS_TO_BUILD!$BINDINGS_TO_BUILD$ac_delim ALL_BINDINGS!$ALL_BINDINGS$ac_delim OCAML_LIBDIR!$OCAML_LIBDIR$ac_delim ENABLE_VISIBILITY_INLINES_HIDDEN!$ENABLE_VISIBILITY_INLINES_HIDDEN$ac_delim -RPATH!$RPATH$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then @@ -21975,12 +21996,13 @@ _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF +RPATH!$RPATH$ac_delim RDYNAMIC!$RDYNAMIC$ac_delim LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 3; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 4; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 -- 1.7.1.GIT -------------- next part -------------- From 9a9f7cc3ef1d1ad646681d430b65a0a15e224c58 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 10 Nov 2010 12:08:28 +0900 Subject: [PATCH 3/4] autoconf: Add --disable-embed-stdcxx to suppress linking libstdc++.a into llvm.dll with --enable-shared on Cygming. Cygwin has stdc++.dll in it's distribution, and we can assume distro's stdc++.dll might be available. --- Makefile.config.in | 3 +++ autoconf/configure.ac | 12 ++++++++++++ tools/llvm-shlib/Makefile | 5 +++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/Makefile.config.in b/Makefile.config.in index 73d2d87..5c73758 100644 --- a/Makefile.config.in +++ b/Makefile.config.in @@ -279,6 +279,9 @@ ENABLE_PIC := @ENABLE_PIC@ # Do we want to build a shared library and link the tools with it? ENABLE_SHARED := @ENABLE_SHARED@ +# Do we want to link the stdc++ into a shared library? (Cygming) +ENABLE_EMBED_STDCXX := @ENABLE_EMBED_STDCXX@ + # Use -fvisibility-inlines-hidden? ENABLE_VISIBILITY_INLINES_HIDDEN := @ENABLE_VISIBILITY_INLINES_HIDDEN@ diff --git a/autoconf/configure.ac b/autoconf/configure.ac index 93a31c8..0cc3d3e 100644 --- a/autoconf/configure.ac +++ b/autoconf/configure.ac @@ -568,6 +568,18 @@ case "$enableval" in *) AC_MSG_ERROR([Invalid setting for --enable-shared. Use "yes" or "no"]) ;; esac +dnl Allow libstdc++ is embedded in LLVM.dll. +AC_ARG_ENABLE(embed-stdcxx, + AS_HELP_STRING([--enable-embed-stdcxx], + [Build a shared library with embedded libstdc++ for Win32 DLL (default is YES)]),, + enableval=default) +case "$enableval" in + yes) AC_SUBST(ENABLE_EMBED_STDCXX,[1]) ;; + no) AC_SUBST(ENABLE_EMBED_STDCXX,[0]) ;; + default) AC_SUBST(ENABLE_EMBED_STDCXX,[1]) ;; + *) AC_MSG_ERROR([Invalid setting for --enable-embed-stdcxx. Use "yes" or "no"]) ;; +esac + dnl Enable embedding timestamp information into build. AC_ARG_ENABLE(timestamps, AS_HELP_STRING([--enable-timestamps], diff --git a/tools/llvm-shlib/Makefile b/tools/llvm-shlib/Makefile index 60b5435..e7605c8 100644 --- a/tools/llvm-shlib/Makefile +++ b/tools/llvm-shlib/Makefile @@ -18,11 +18,12 @@ SHARED_LIBRARY = 1 include $(LEVEL)/Makefile.config ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW)) - EXPORTED_SYMBOL_FILE = $(ObjDir)/$(LIBRARYNAME).exports + EXPORTED_SYMBOL_FILE = $(ObjDir)/$(LIBRARYNAME).exports + ifeq (1,$(ENABLE_EMBED_STDCXX)) # It is needed to force static-stdc++.a linked. - # FIXME: It should be omitted when configure detects system's stdc++.dll. SHLIB_FRAG_NAMES += stdc++.a.o + endif endif -- 1.7.1.GIT -------------- next part -------------- From a4942cc8a286cc6e8e4bbcb4d953fb01537cd721 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 10 Nov 2010 12:09:26 +0900 Subject: [PATCH 4/4] configure: Regenerated for --disable-embed-stdcxx. --- configure | 31 +++++++++++++++++++++++++++---- 1 files changed, 27 insertions(+), 4 deletions(-) diff --git a/configure b/configure index ac24889..2a739d3 100755 --- a/configure +++ b/configure @@ -694,6 +694,7 @@ ENABLE_THREADS ENABLE_PTHREADS ENABLE_PIC ENABLE_SHARED +ENABLE_EMBED_STDCXX ENABLE_TIMESTAMPS TARGETS_TO_BUILD LLVM_ENUM_TARGETS @@ -1421,6 +1422,8 @@ Optional Features: is YES) --enable-shared Build a shared library and link tools against it (default is NO) + --enable-embed-stdcxx Build a shared library with embedded libstdc++ for + Win32 DLL (default is YES) --enable-timestamps Enable embedding timestamp information in build (default is YES) --enable-targets Build specific host targets: all or @@ -4999,6 +5002,25 @@ echo "$as_me: error: Invalid setting for --enable-shared. Use \"yes\" or \"no\"" { (exit 1); exit 1; }; } ;; esac +# Check whether --enable-embed-stdcxx was given. +if test "${enable_embed_stdcxx+set}" = set; then + enableval=$enable_embed_stdcxx; +else + enableval=default +fi + +case "$enableval" in + yes) ENABLE_EMBED_STDCXX=1 + ;; + no) ENABLE_EMBED_STDCXX=0 + ;; + default) ENABLE_EMBED_STDCXX=1 + ;; + *) { { echo "$as_me:$LINENO: error: Invalid setting for --enable-embed-stdcxx. Use \"yes\" or \"no\"" >&5 +echo "$as_me: error: Invalid setting for --enable-embed-stdcxx. Use \"yes\" or \"no\"" >&2;} + { (exit 1); exit 1; }; } ;; +esac + # Check whether --enable-timestamps was given. if test "${enable_timestamps+set}" = set; then enableval=$enable_timestamps; @@ -11539,7 +11561,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <conf$$subs.sed <<_ACEOF +LLVM_ENUM_ASM_PARSERS!$LLVM_ENUM_ASM_PARSERS$ac_delim LLVM_ENUM_DISASSEMBLERS!$LLVM_ENUM_DISASSEMBLERS$ac_delim ENABLE_CBE_PRINTF_A!$ENABLE_CBE_PRINTF_A$ac_delim CLANGPATH!$CLANGPATH$ac_delim @@ -21954,7 +21977,6 @@ LLVM_CONFIGTIME!$LLVM_CONFIGTIME$ac_delim BINDINGS_TO_BUILD!$BINDINGS_TO_BUILD$ac_delim ALL_BINDINGS!$ALL_BINDINGS$ac_delim OCAML_LIBDIR!$OCAML_LIBDIR$ac_delim -ENABLE_VISIBILITY_INLINES_HIDDEN!$ENABLE_VISIBILITY_INLINES_HIDDEN$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then @@ -21996,13 +22018,14 @@ _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF +ENABLE_VISIBILITY_INLINES_HIDDEN!$ENABLE_VISIBILITY_INLINES_HIDDEN$ac_delim RPATH!$RPATH$ac_delim RDYNAMIC!$RDYNAMIC$ac_delim LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 4; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 5; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 -- 1.7.1.GIT From geek4civic at gmail.com Sun Dec 26 19:46:15 2010 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Mon, 27 Dec 2010 10:46:15 +0900 Subject: [llvm-commits] [Review request][Win] CMake & Lit: the new feature "LLVM_LIT_TOOLS_DIR" In-Reply-To: <87zkshc15m.fsf@telefonica.net> References: <87zkshc15m.fsf@telefonica.net> Message-ID: Ping. 2010/12/7 ?scar Fuentes : >> +set(LLVM_LIT_TOOLS_DIR "" CACHE PATH "Path to GnuWin32 tools") > > I guess that other ports can be used (MSYS, Cygwin, etc) So instead of > GnuWin32 maybe you should list the names of the required tools (cmp, > sed, grep) on the docstring. > > +set(LLVM_LIT_TOOLS_DIR "" CACHE PATH > + ? "Path to GNU cmp, grep and sed. Used when running tests.") I apologize to respond too later. I intended, for it, easier case. It might be specified only for gnuwin32 and would be useful on msbuild, mingw and msys. On cygwin, lit.tools_dir would not be used. Cygwin's python does not know he might be on win32 himself. (and in general, cygwin's toolchain should be mature) ...Takumi From rafael.espindola at gmail.com Sun Dec 26 20:03:24 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Mon, 27 Dec 2010 02:03:24 -0000 Subject: [llvm-commits] [llvm] r122579 - in /llvm/trunk: lib/MC/ELFObjectWriter.cpp test/MC/ELF/relocation.s Message-ID: <20101227020324.D51C42A6C12C@llvm.org> Author: rafael Date: Sun Dec 26 20:03:24 2010 New Revision: 122579 URL: http://llvm.org/viewvc/llvm-project?rev=122579&view=rev Log: Handle reloc_riprel_4byte_movq_load. Should make the bots happy. Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp llvm/trunk/test/MC/ELF/relocation.s Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=122579&r1=122578&r2=122579&view=diff ============================================================================== --- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Sun Dec 26 20:03:24 2010 @@ -1610,6 +1610,7 @@ assert(Modifier == MCSymbolRefExpr::VK_None); Type = ELF::R_X86_64_PC64; break; + case X86::reloc_riprel_4byte_movq_load: case FK_Data_4: // FIXME? case X86::reloc_riprel_4byte: case FK_PCRel_4: Modified: llvm/trunk/test/MC/ELF/relocation.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/relocation.s?rev=122579&r1=122578&r2=122579&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/relocation.s (original) +++ llvm/trunk/test/MC/ELF/relocation.s Sun Dec 26 20:03:24 2010 @@ -15,6 +15,7 @@ leaq foo at TLSLD(%rip), %rdi # R_X86_64_TLSLD leaq foo at DTPOFF(%rax), %rcx # R_X86_64_DTPOFF32 pushq $bar + movq foo(%rip), %rdx // CHECK: # Section 0x00000001 @@ -98,3 +99,9 @@ // CHECK-NEXT: ('r_sym', 0x00000002) // CHECK-NEXT: ('r_type', 0x0000000b) // CHECK-NEXT: ('r_addend', 0x00000000) + +// CHECK: # Relocation 0x0000000c +// CHECK-NEXT: (('r_offset', 0x00000055) +// CHECK-NEXT: ('r_sym', 0x00000006) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0xfffffffc) From ofv at wanadoo.es Sun Dec 26 20:26:14 2010 From: ofv at wanadoo.es (=?utf-8?Q?=C3=93scar?= Fuentes) Date: Mon, 27 Dec 2010 03:26:14 +0100 Subject: [llvm-commits] [Review request][Win] CMake & Lit: the new feature "LLVM_LIT_TOOLS_DIR" In-Reply-To: (NAKAMURA Takumi's message of "Mon, 27 Dec 2010 10:46:15 +0900") References: <87zkshc15m.fsf@telefonica.net> Message-ID: <878vzc3q9l.fsf@telefonica.net> NAKAMURA Takumi writes: > 2010/12/7 ?scar Fuentes : >>> +set(LLVM_LIT_TOOLS_DIR "" CACHE PATH "Path to GnuWin32 tools") >> >> I guess that other ports can be used (MSYS, Cygwin, etc) So instead of >> GnuWin32 maybe you should list the names of the required tools (cmp, >> sed, grep) on the docstring. >> >> +set(LLVM_LIT_TOOLS_DIR "" CACHE PATH >> + ? "Path to GNU cmp, grep and sed. Used when running tests.") > > I apologize to respond too later. > > I intended, for it, easier case. It might be specified only for > gnuwin32 and would be useful on msbuild, mingw and msys. > > On cygwin, lit.tools_dir would not be used. Cygwin's python does not > know he might be on win32 himself. > (and in general, cygwin's toolchain should be mature) Please note too that by mentioning GnuWin32 in the docstring the user may think that it is required for running tests. Anyways, this is not a reason for blocking the patch. From fvbommel at gmail.com Sun Dec 26 20:48:49 2010 From: fvbommel at gmail.com (Frits van Bommel) Date: Mon, 27 Dec 2010 03:48:49 +0100 Subject: [llvm-commits] [llvm] r122574 - /llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp In-Reply-To: <20101227000323.BB9F62A6C12C@llvm.org> References: <20101227000323.BB9F62A6C12C@llvm.org> Message-ID: On Mon, Dec 27, 2010 at 1:03 AM, Chris Lattner wrote: > - > - ? ?MadeChange |= processLoopStore(SI, BECount); > + ? ?WeakVH InstPtr; Shouldn't InstPtr be initialized to something? (Say, SI?) > + ? ?if (processLoopStore(SI, BECount)) { You're no longer setting MadeChange. > + ? ? ?// If processing the store invalidated our iterator, start over from the > + ? ? ?// head of the loop. > + ? ? ?if (InstPtr == 0) > + ? ? ? ?I = BB->begin(); > + ? ?} > ? } > > ? return MadeChange; From bigcheesegs at gmail.com Sun Dec 26 21:21:41 2010 From: bigcheesegs at gmail.com (Michael J. Spencer) Date: Mon, 27 Dec 2010 03:21:41 -0000 Subject: [llvm-commits] [llvm] r122580 - in /llvm/trunk: include/llvm/Support/PathV1.h lib/Support/Unix/Path.inc Message-ID: <20101227032141.873EC2A6C12C@llvm.org> Author: mspencer Date: Sun Dec 26 21:21:41 2010 New Revision: 122580 URL: http://llvm.org/viewvc/llvm-project?rev=122580&view=rev Log: Support/PathV1: Deprecate GetRootDirectory. Modified: llvm/trunk/include/llvm/Support/PathV1.h llvm/trunk/lib/Support/Unix/Path.inc Modified: llvm/trunk/include/llvm/Support/PathV1.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/PathV1.h?rev=122580&r1=122579&r2=122580&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/PathV1.h (original) +++ llvm/trunk/include/llvm/Support/PathV1.h Sun Dec 26 21:21:41 2010 @@ -98,7 +98,8 @@ /// it is file:///. Other operating systems may have different notions of /// what the root directory is or none at all. In that case, a consistent /// default root directory will be used. - static Path GetRootDirectory(); + LLVM_ATTRIBUTE_DEPRECATED(static Path GetRootDirectory(), + LLVMV_PATH_DEPRECATED_MSG(NOTHING)); /// Construct a path to a unique temporary directory that is created in /// a "standard" place for the operating system. The directory is Modified: llvm/trunk/lib/Support/Unix/Path.inc URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/Path.inc?rev=122580&r1=122579&r2=122580&view=diff ============================================================================== --- llvm/trunk/lib/Support/Unix/Path.inc (original) +++ llvm/trunk/lib/Support/Unix/Path.inc Sun Dec 26 21:21:41 2010 @@ -242,12 +242,11 @@ Path Path::GetUserHomeDirectory() { const char* home = getenv("HOME"); - if (home) { - Path result; - if (result.set(home)) - return result; - } - return GetRootDirectory(); + Path result; + if (home && result.set(home)) + return result; + result.set("/"); + return result; } Path From zwarich at apple.com Sun Dec 26 23:17:23 2010 From: zwarich at apple.com (Cameron Zwarich) Date: Mon, 27 Dec 2010 05:17:23 -0000 Subject: [llvm-commits] [llvm] r122581 - /llvm/trunk/lib/CodeGen/MachineVerifier.cpp Message-ID: <20101227051723.525822A6C12C@llvm.org> Author: zwarich Date: Sun Dec 26 23:17:23 2010 New Revision: 122581 URL: http://llvm.org/viewvc/llvm-project?rev=122581&view=rev Log: Add knowledge of phi-def and phi-kill valnos to MachineVerifier's predecessor valno verification. The "Different value live out of predecessor" check is incorrect in the case of phi-def valnos, so just skip that check for phi-def valnos and instead check that all of the valnos for predecessors have phi-kill. Fixes PR8863. Modified: llvm/trunk/lib/CodeGen/MachineVerifier.cpp Modified: llvm/trunk/lib/CodeGen/MachineVerifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineVerifier.cpp?rev=122581&r1=122580&r2=122581&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineVerifier.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineVerifier.cpp Sun Dec 26 23:17:23 2010 @@ -1146,7 +1146,23 @@ *OS << "Valno #" << VNI->id << " live into BB#" << MFI->getNumber() << '@' << LiveInts->getMBBStartIdx(MFI) << ", not live at " << PEnd << " in " << LI << '\n'; - } else if (PVNI != VNI) { + continue; + } + + if (VNI->isPHIDef() && VNI->def == LiveInts->getMBBStartIdx(MFI)) { + if (!PVNI->hasPHIKill()) { + report("Value live out of predecessor doesn't have PHIKill", MF); + *OS << "Valno #" << PVNI->id << " live out of BB#" + << (*PI)->getNumber() << '@' << PEnd + << " doesn't have PHIKill, but Valno #" << VNI->id + << " is PHIDef and defined at the beginning of BB#" + << MFI->getNumber() << '@' << LiveInts->getMBBStartIdx(MFI) + << " in " << LI << '\n'; + } + continue; + } + + if (PVNI != VNI) { report("Different value live out of predecessor", *PI); *OS << "Valno #" << PVNI->id << " live out of BB#" << (*PI)->getNumber() << '@' << PEnd From venkatra at cs.wisc.edu Sun Dec 26 22:33:14 2010 From: venkatra at cs.wisc.edu (Venkatraman Govindaraju) Date: Sun, 26 Dec 2010 22:33:14 -0600 Subject: [llvm-commits] [PATCH] Sparc backend fixes Message-ID: Hello, The attached path fixes the following three issues with the Sparc backend. 1. EmitInstrWithCustomInserter() in SparcISelLowering splices MachineBasicBlock before inserting them into the machine function. It corrupts the def-use chain of MachineOperand and causes a infinite loop in llc. Now, the patch avoids this by inserting the machine basicblocks into the machine function before splicing the original basicblock. 2. When the bitcode has "select_cc", Sparc backend may not generate correct assembly code. Since select_ccs do not have ICC/FCC as Uses, the corresponding def of ICC/FCC can be marked as dead and removed. Now, the select_ccs have ICC/FCC as Uses. 3. Sparc backend does not know about Y register. It causes the "rdy" and "wry" instructions to be marked as dead and removed. Now it knows about Y and generate correct code. Please let me know if the patch is okay to commit. Thanks, Venkatraman -------------- next part -------------- A non-text attachment was scrubbed... Name: sparc-backend-fixes.patch Type: application/octet-stream Size: 4144 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101226/96164592/attachment.obj