llvm.org GIT mirror llvm / 0a3cc8f
Revert 253497 and 253539 to try to fix clang-cmake-mips buildbot. It caused link errors of the form: InstrProfiling.c:(.text.__llvm_profile_instrument_target+0x1c0): undefined reference to `__sync_fetch_and_add_8' We had a network outage at the time of the commit so the first build to show a problem is http://lab.llvm.org:8011/builders/clang-cmake-mips/builds/10827 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253656 91177308-0d34-0410-b5e6-96231b3b80d8 Daniel Sanders 3 years ago
5 changed file(s) with 9 addition(s) and 78 deletion(s). Raw diff Collapse all Expand all
225225 while (I != IE && I->Value < J->Value)
226226 ++I;
227227 if (I != IE && I->Value == J->Value) {
228 I->Count = SaturatingAdd(I->Count, J->Count);
228 I->Count += J->Count;
229229 ++I;
230230 continue;
231231 }
176176 /// Sample counts accumulate using saturating arithmetic, to avoid wrapping
177177 /// around unsigned integers.
178178 void addSamples(uint64_t S) {
179 NumSamples = SaturatingAdd(NumSamples, S);
179 if (NumSamples <= std::numeric_limits::max() - S)
180 NumSamples += S;
181 else
182 NumSamples = std::numeric_limits::max();
180183 }
181184
182185 /// Add called function \p F with samples \p S.
185188 /// around unsigned integers.
186189 void addCalledTarget(StringRef F, uint64_t S) {
187190 uint64_t &TargetSamples = CallTargets[F];
188 TargetSamples = SaturatingAdd(TargetSamples, S);
191 if (TargetSamples <= std::numeric_limits::max() - S)
192 TargetSamples += S;
193 else
194 TargetSamples = std::numeric_limits::max();
189195 }
190196
191197 /// Return true if this sample record contains function calls.
652652 return int64_t(X << (64 - B)) >> (64 - B);
653653 }
654654
655 /// \brief Add two unsigned integers, X and Y, of type T.
656 /// Clamp the result to the maximum representable value of T on overflow.
657 template
658 typename std::enable_if::value, T>::type
659 SaturatingAdd(T X, T Y) {
660 // Hacker's Delight, p. 29
661 T Z = X + Y;
662 if (Z < X || Z < Y)
663 return std::numeric_limits::max();
664 else
665 return Z;
666 }
667
668 /// \brief Multiply two unsigned integers, X and Y, of type T.
669 /// Clamp the result to the maximum representable value of T on overflow.
670 template
671 typename std::enable_if::value, T>::type
672 SaturatingMultiply(T X, T Y) {
673 // Hacker's Delight, p. 30
674 T Z = X * Y;
675 if (Y != 0 && Z / Y != X)
676 return std::numeric_limits::max();
677 else
678 return Z;
679 }
680
681655 extern const float huge_valf;
682656 } // End llvm namespace
683657
349349 ASSERT_EQ(2U, VD_4[2].Count);
350350 }
351351
352 TEST_F(InstrProfTest, get_icall_data_merge1_saturation) {
353 const uint64_t Max = std::numeric_limits::max();
354
355 InstrProfRecord Record1("caller", 0x1234, {1});
356 InstrProfRecord Record2("caller", 0x1234, {1});
357 InstrProfRecord Record3("callee1", 0x1235, {3, 4});
358
359 Record1.reserveSites(IPVK_IndirectCallTarget, 1);
360 InstrProfValueData VD1[] = {{(uint64_t) "callee1", 1}};
361 Record1.addValueData(IPVK_IndirectCallTarget, 0, VD1, 1, nullptr);
362
363 Record2.reserveSites(IPVK_IndirectCallTarget, 1);
364 InstrProfValueData VD2[] = {{(uint64_t) "callee1", Max}};
365 Record2.addValueData(IPVK_IndirectCallTarget, 0, VD2, 1, nullptr);
366
367 Writer.addRecord(std::move(Record1));
368 Writer.addRecord(std::move(Record2));
369 Writer.addRecord(std::move(Record3));
370
371 auto Profile = Writer.writeBuffer();
372 readProfile(std::move(Profile));
373
374 // Verify saturation of counts.
375 ErrorOr R = Reader->getInstrProfRecord("caller", 0x1234);
376 ASSERT_TRUE(NoError(R.getError()));
377 ASSERT_EQ(1U, R.get().getNumValueSites(IPVK_IndirectCallTarget));
378 std::unique_ptr VD =
379 R.get().getValueForSite(IPVK_IndirectCallTarget, 0);
380 ASSERT_EQ(StringRef("callee1"), StringRef((const char *)VD[0].Value, 7));
381 ASSERT_EQ(Max, VD[0].Count);
382 }
383
384352 TEST_F(InstrProfTest, get_max_function_count) {
385353 InstrProfRecord Record1("foo", 0x1234, {1ULL << 31, 2});
386354 InstrProfRecord Record2("bar", 0, {1ULL << 63});
189189 EXPECT_EQ(552u, RoundUpToAlignment(321, 255, 42));
190190 }
191191
192 template
193 void SaturatingAddTestHelper()
194 {
195 const T Max = std::numeric_limits::max();
196 EXPECT_EQ(T(3), SaturatingAdd(T(1), T(2)));
197 EXPECT_EQ(Max, SaturatingAdd(Max, T(1)));
198 EXPECT_EQ(Max, SaturatingAdd(T(1), Max));
199 EXPECT_EQ(Max, SaturatingAdd(Max, Max));
200192 }
201
202 TEST(MathExtras, SaturatingAdd) {
203 SaturatingAddTestHelper();
204 SaturatingAddTestHelper();
205 SaturatingAddTestHelper();
206 SaturatingAddTestHelper();
207 }
208
209 }