Index: include/llvm/Support/BlockFrequency.h =================================================================== --- include/llvm/Support/BlockFrequency.h +++ include/llvm/Support/BlockFrequency.h @@ -71,6 +71,10 @@ bool operator>=(BlockFrequency RHS) const { return Frequency >= RHS.Frequency; } + + bool operator==(BlockFrequency RHS) const { + return Frequency == RHS.Frequency; + } }; } Index: lib/Transforms/Scalar/ConstantHoisting.cpp =================================================================== --- lib/Transforms/Scalar/ConstantHoisting.cpp +++ lib/Transforms/Scalar/ConstantHoisting.cpp @@ -231,7 +231,8 @@ // Return the optimal insert points in BBs. if (Node == Entry) { BBs.clear(); - if (InsertPtsFreq > BFI.getBlockFreq(Node)) + if (InsertPtsFreq > BFI.getBlockFreq(Node) || + (InsertPtsFreq == BFI.getBlockFreq(Node) && InsertPts.size() > 1)) BBs.insert(Entry); else BBs.insert(InsertPts.begin(), InsertPts.end()); @@ -244,7 +245,15 @@ SmallPtrSet &ParentInsertPts = InsertPtsMap[Parent].first; BlockFrequency &ParentPtsFreq = InsertPtsMap[Parent].second; // Choose to insert in Node or in subtree of Node. - if (InsertPtsFreq > BFI.getBlockFreq(Node) || NodeInBBs) { + // Don't hoist to EHPad because we may not find a proper place to insert + // in EHPad. + // If the total frequency of InsertPts is the same as the frequency of the + // target Node, and InsertPts contains more than one nodes, choose hoisting + // to reduce code size. + if (NodeInBBs || + (!Node->isEHPad() && + (InsertPtsFreq > BFI.getBlockFreq(Node) || + (InsertPtsFreq == BFI.getBlockFreq(Node) && InsertPts.size() > 1)))) { ParentInsertPts.insert(Node); ParentPtsFreq += BFI.getBlockFreq(Node); } else { Index: test/CodeGen/X86/constant-hoisting-bfi.ll =================================================================== --- test/CodeGen/X86/constant-hoisting-bfi.ll +++ test/CodeGen/X86/constant-hoisting-bfi.ll @@ -4,13 +4,13 @@ ; Check when BFI is enabled for constant hoisting, constant 214748364701 ; will not be hoisted to the func entry. -; CHECK-LABEL: @foo( +; CHECK-LABEL: @test1( ; CHECK: entry: ; CHECK-NOT: bitcast i64 214748364701 to i64 ; CHECK: if.then: ; Function Attrs: norecurse nounwind uwtable -define i64 @foo(i64* nocapture %a) { +define i64 @test1(i64* nocapture %a) { entry: %arrayidx = getelementptr inbounds i64, i64* %a, i64 9 %t0 = load i64, i64* %arrayidx, align 8 @@ -52,7 +52,7 @@ ; in while.body will be hoisted to while.body.preheader. 214748364701 in ; if.then16 and if.else10 will be merged and hoisted to the beginning of ; if.else10 because if.else10 dominates if.then16. -; CHECK-LABEL: @goo( +; CHECK-LABEL: @test2( ; CHECK: entry: ; CHECK-NOT: bitcast i64 214748364701 to i64 ; CHECK: while.body.preheader: @@ -61,7 +61,7 @@ ; CHECK: if.else10: ; CHECK-NEXT: bitcast i64 214748364701 to i64 ; CHECK-NOT: bitcast i64 214748364701 to i64 -define i64 @goo(i64* nocapture %a) { +define i64 @test2(i64* nocapture %a) { entry: %arrayidx = getelementptr inbounds i64, i64* %a, i64 9 %t0 = load i64, i64* %arrayidx, align 8 @@ -113,3 +113,43 @@ } !0 = !{!"branch_weights", i32 1, i32 2000} + +; 214748364701 will be hoisted to entry block to reduce code size. +; CHECK-LABEL: @test3( +; CHECK: entry: +; CHECK-NEXT: %const = bitcast i64 214748364701 to i64 +define i64 @test3(i64 %t0) { +entry: + %cmp = icmp ult i64 %t0, 56 + br i1 %cmp, label %if.then, label %if.else + +if.then: + %add1 = add i64 %t0, 214748364701 + br label %return + +if.else: + %add2 = add i64 %t0, 214748364701 + br label %return + +return: + %retval = phi i64 [ %add1, %if.then ], [ %add2, %if.else ] + ret i64 %retval +} + +; 214748364701 will not be hoisted to entry block because it will only +; increase its live range. +; CHECK-LABEL: @test4( +; CHECK: nextblock: +; CHECK-NEXT: %add1 = add i64 %t0, 214748364701 +define i64 @test4(i64 %t0) { +entry: + %cmp = icmp ult i64 %t0, 56 + br label %nextblock + +nextblock: + %add1 = add i64 %t0, 214748364701 + br label %return + +return: + ret i64 %add1 +}