@@ -302,98 +302,7 @@ static BinaryOperator *LowerNegateToMultiply(Instruction *Neg) {
302
302
return Res;
303
303
}
304
304
305
- // / Returns k such that lambda(2^Bitwidth) = 2^k, where lambda is the Carmichael
306
- // / function. This means that x^(2^k) === 1 mod 2^Bitwidth for
307
- // / every odd x, i.e. x^(2^k) = 1 for every odd x in Bitwidth-bit arithmetic.
308
- // / Note that 0 <= k < Bitwidth, and if Bitwidth > 3 then x^(2^k) = 0 for every
309
- // / even x in Bitwidth-bit arithmetic.
310
- static unsigned CarmichaelShift (unsigned Bitwidth) {
311
- if (Bitwidth < 3 )
312
- return Bitwidth - 1 ;
313
- return Bitwidth - 2 ;
314
- }
315
-
316
- // / Add the extra weight 'RHS' to the existing weight 'LHS',
317
- // / reducing the combined weight using any special properties of the operation.
318
- // / The existing weight LHS represents the computation X op X op ... op X where
319
- // / X occurs LHS times. The combined weight represents X op X op ... op X with
320
- // / X occurring LHS + RHS times. If op is "Xor" for example then the combined
321
- // / operation is equivalent to X if LHS + RHS is odd, or 0 if LHS + RHS is even;
322
- // / the routine returns 1 in LHS in the first case, and 0 in LHS in the second.
323
- static void IncorporateWeight (APInt &LHS, const APInt &RHS, unsigned Opcode) {
324
- // If we were working with infinite precision arithmetic then the combined
325
- // weight would be LHS + RHS. But we are using finite precision arithmetic,
326
- // and the APInt sum LHS + RHS may not be correct if it wraps (it is correct
327
- // for nilpotent operations and addition, but not for idempotent operations
328
- // and multiplication), so it is important to correctly reduce the combined
329
- // weight back into range if wrapping would be wrong.
330
-
331
- // If RHS is zero then the weight didn't change.
332
- if (RHS.isMinValue ())
333
- return ;
334
- // If LHS is zero then the combined weight is RHS.
335
- if (LHS.isMinValue ()) {
336
- LHS = RHS;
337
- return ;
338
- }
339
- // From this point on we know that neither LHS nor RHS is zero.
340
-
341
- if (Instruction::isIdempotent (Opcode)) {
342
- // Idempotent means X op X === X, so any non-zero weight is equivalent to a
343
- // weight of 1. Keeping weights at zero or one also means that wrapping is
344
- // not a problem.
345
- assert (LHS == 1 && RHS == 1 && " Weights not reduced!" );
346
- return ; // Return a weight of 1.
347
- }
348
- if (Instruction::isNilpotent (Opcode)) {
349
- // Nilpotent means X op X === 0, so reduce weights modulo 2.
350
- assert (LHS == 1 && RHS == 1 && " Weights not reduced!" );
351
- LHS = 0 ; // 1 + 1 === 0 modulo 2.
352
- return ;
353
- }
354
- if (Opcode == Instruction::Add || Opcode == Instruction::FAdd) {
355
- // TODO: Reduce the weight by exploiting nsw/nuw?
356
- LHS += RHS;
357
- return ;
358
- }
359
-
360
- assert ((Opcode == Instruction::Mul || Opcode == Instruction::FMul) &&
361
- " Unknown associative operation!" );
362
- unsigned Bitwidth = LHS.getBitWidth ();
363
- // If CM is the Carmichael number then a weight W satisfying W >= CM+Bitwidth
364
- // can be replaced with W-CM. That's because x^W=x^(W-CM) for every Bitwidth
365
- // bit number x, since either x is odd in which case x^CM = 1, or x is even in
366
- // which case both x^W and x^(W - CM) are zero. By subtracting off multiples
367
- // of CM like this weights can always be reduced to the range [0, CM+Bitwidth)
368
- // which by a happy accident means that they can always be represented using
369
- // Bitwidth bits.
370
- // TODO: Reduce the weight by exploiting nsw/nuw? (Could do much better than
371
- // the Carmichael number).
372
- if (Bitwidth > 3 ) {
373
- // / CM - The value of Carmichael's lambda function.
374
- APInt CM = APInt::getOneBitSet (Bitwidth, CarmichaelShift (Bitwidth));
375
- // Any weight W >= Threshold can be replaced with W - CM.
376
- APInt Threshold = CM + Bitwidth;
377
- assert (LHS.ult (Threshold) && RHS.ult (Threshold) && " Weights not reduced!" );
378
- // For Bitwidth 4 or more the following sum does not overflow.
379
- LHS += RHS;
380
- while (LHS.uge (Threshold))
381
- LHS -= CM;
382
- } else {
383
- // To avoid problems with overflow do everything the same as above but using
384
- // a larger type.
385
- unsigned CM = 1U << CarmichaelShift (Bitwidth);
386
- unsigned Threshold = CM + Bitwidth;
387
- assert (LHS.getZExtValue () < Threshold && RHS.getZExtValue () < Threshold &&
388
- " Weights not reduced!" );
389
- unsigned Total = LHS.getZExtValue () + RHS.getZExtValue ();
390
- while (Total >= Threshold)
391
- Total -= CM;
392
- LHS = Total;
393
- }
394
- }
395
-
396
- using RepeatedValue = std::pair<Value*, APInt>;
305
+ using RepeatedValue = std::pair<Value *, uint64_t >;
397
306
398
307
// / Given an associative binary expression, return the leaf
399
308
// / nodes in Ops along with their weights (how many times the leaf occurs). The
@@ -475,7 +384,6 @@ static bool LinearizeExprTree(Instruction *I,
475
384
assert ((isa<UnaryOperator>(I) || isa<BinaryOperator>(I)) &&
476
385
" Expected a UnaryOperator or BinaryOperator!" );
477
386
LLVM_DEBUG (dbgs () << " LINEARIZE: " << *I << ' \n ' );
478
- unsigned Bitwidth = I->getType ()->getScalarType ()->getPrimitiveSizeInBits ();
479
387
unsigned Opcode = I->getOpcode ();
480
388
assert (I->isAssociative () && I->isCommutative () &&
481
389
" Expected an associative and commutative operation!" );
@@ -490,8 +398,8 @@ static bool LinearizeExprTree(Instruction *I,
490
398
// with their weights, representing a certain number of paths to the operator.
491
399
// If an operator occurs in the worklist multiple times then we found multiple
492
400
// ways to get to it.
493
- SmallVector<std::pair<Instruction*, APInt >, 8 > Worklist; // (Op, Weight)
494
- Worklist.push_back (std::make_pair (I, APInt (Bitwidth, 1 ) ));
401
+ SmallVector<std::pair<Instruction *, uint64_t >, 8 > Worklist; // (Op, Weight)
402
+ Worklist.push_back (std::make_pair (I, 1 ));
495
403
bool Changed = false ;
496
404
497
405
// Leaves of the expression are values that either aren't the right kind of
@@ -509,7 +417,7 @@ static bool LinearizeExprTree(Instruction *I,
509
417
510
418
// Leaves - Keeps track of the set of putative leaves as well as the number of
511
419
// paths to each leaf seen so far.
512
- using LeafMap = DenseMap<Value *, APInt >;
420
+ using LeafMap = DenseMap<Value *, uint64_t >;
513
421
LeafMap Leaves; // Leaf -> Total weight so far.
514
422
SmallVector<Value *, 8 > LeafOrder; // Ensure deterministic leaf output order.
515
423
const DataLayout DL = I->getModule ()->getDataLayout ();
@@ -518,8 +426,8 @@ static bool LinearizeExprTree(Instruction *I,
518
426
SmallPtrSet<Value *, 8 > Visited; // For checking the iteration scheme.
519
427
#endif
520
428
while (!Worklist.empty ()) {
521
- std::pair<Instruction*, APInt> P = Worklist. pop_back_val ();
522
- I = P. first ; // We examine the operands of this binary operator.
429
+ // We examine the operands of this binary operator.
430
+ auto [I, Weight] = Worklist. pop_back_val ();
523
431
524
432
if (isa<OverflowingBinaryOperator>(I)) {
525
433
Flags.HasNUW &= I->hasNoUnsignedWrap ();
@@ -528,7 +436,6 @@ static bool LinearizeExprTree(Instruction *I,
528
436
529
437
for (unsigned OpIdx = 0 ; OpIdx < I->getNumOperands (); ++OpIdx) { // Visit operands.
530
438
Value *Op = I->getOperand (OpIdx);
531
- APInt Weight = P.second ; // Number of paths to this operand.
532
439
LLVM_DEBUG (dbgs () << " OPERAND: " << *Op << " (" << Weight << " )\n " );
533
440
assert (!Op->use_empty () && " No uses, so how did we get to it?!" );
534
441
@@ -562,7 +469,8 @@ static bool LinearizeExprTree(Instruction *I,
562
469
" In leaf map but not visited!" );
563
470
564
471
// Update the number of paths to the leaf.
565
- IncorporateWeight (It->second , Weight, Opcode);
472
+ It->second += Weight;
473
+ assert (It->second >= Weight && " Weight overflows" );
566
474
567
475
// If we still have uses that are not accounted for by the expression
568
476
// then it is not safe to modify the value.
@@ -625,10 +533,7 @@ static bool LinearizeExprTree(Instruction *I,
625
533
// Node initially thought to be a leaf wasn't.
626
534
continue ;
627
535
assert (!isReassociableOp (V, Opcode) && " Shouldn't be a leaf!" );
628
- APInt Weight = It->second ;
629
- if (Weight.isMinValue ())
630
- // Leaf already output or weight reduction eliminated it.
631
- continue ;
536
+ uint64_t Weight = It->second ;
632
537
// Ensure the leaf is only output once.
633
538
It->second = 0 ;
634
539
Ops.push_back (std::make_pair (V, Weight));
@@ -642,7 +547,7 @@ static bool LinearizeExprTree(Instruction *I,
642
547
if (Ops.empty ()) {
643
548
Constant *Identity = ConstantExpr::getBinOpIdentity (Opcode, I->getType ());
644
549
assert (Identity && " Associative operation without identity!" );
645
- Ops.emplace_back (Identity, APInt (Bitwidth, 1 ) );
550
+ Ops.emplace_back (Identity, 1 );
646
551
}
647
552
648
553
return Changed;
@@ -1188,8 +1093,7 @@ Value *ReassociatePass::RemoveFactorFromExpression(Value *V, Value *Factor) {
1188
1093
Factors.reserve (Tree.size ());
1189
1094
for (unsigned i = 0 , e = Tree.size (); i != e; ++i) {
1190
1095
RepeatedValue E = Tree[i];
1191
- Factors.append (E.second .getZExtValue (),
1192
- ValueEntry (getRank (E.first ), E.first ));
1096
+ Factors.append (E.second , ValueEntry (getRank (E.first ), E.first ));
1193
1097
}
1194
1098
1195
1099
bool FoundFactor = false ;
@@ -2368,7 +2272,7 @@ void ReassociatePass::ReassociateExpression(BinaryOperator *I) {
2368
2272
SmallVector<ValueEntry, 8 > Ops;
2369
2273
Ops.reserve (Tree.size ());
2370
2274
for (const RepeatedValue &E : Tree)
2371
- Ops.append (E.second . getZExtValue () , ValueEntry (getRank (E.first ), E.first ));
2275
+ Ops.append (E.second , ValueEntry (getRank (E.first ), E.first ));
2372
2276
2373
2277
LLVM_DEBUG (dbgs () << " RAIn:\t " ; PrintOps (I, Ops); dbgs () << ' \n ' );
2374
2278
0 commit comments