llvm/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp

//===- InstCombinePHI.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the visitPHINode function.
//
//===----------------------------------------------------------------------===//

#include "InstCombineInternal.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Transforms/InstCombine/InstCombiner.h"
#include "llvm/Transforms/Utils/Local.h"
#include <optional>

usingnamespacellvm;
usingnamespacellvm::PatternMatch;

#define DEBUG_TYPE

static cl::opt<unsigned>
MaxNumPhis("instcombine-max-num-phis", cl::init(512),
           cl::desc("Maximum number phis to handle in intptr/ptrint folding"));

STATISTIC(NumPHIsOfInsertValues,
          "Number of phi-of-insertvalue turned into insertvalue-of-phis");
STATISTIC(NumPHIsOfExtractValues,
          "Number of phi-of-extractvalue turned into extractvalue-of-phi");
STATISTIC(NumPHICSEs, "Number of PHI's that got CSE'd");

/// The PHI arguments will be folded into a single operation with a PHI node
/// as input. The debug location of the single operation will be the merged
/// locations of the original PHI node arguments.
void InstCombinerImpl::PHIArgMergedDebugLoc(Instruction *Inst, PHINode &PN) {}

/// If the phi is within a phi web, which is formed by the def-use chain
/// of phis and all the phis in the web are only used in the other phis.
/// In this case, these phis are dead and we will remove all of them.
bool InstCombinerImpl::foldDeadPhiWeb(PHINode &PN) {}

// Replace Integer typed PHI PN if the PHI's value is used as a pointer value.
// If there is an existing pointer typed PHI that produces the same value as PN,
// replace PN and the IntToPtr operation with it. Otherwise, synthesize a new
// PHI node:
//
// Case-1:
// bb1:
//     int_init = PtrToInt(ptr_init)
//     br label %bb2
// bb2:
//    int_val = PHI([int_init, %bb1], [int_val_inc, %bb2]
//    ptr_val = PHI([ptr_init, %bb1], [ptr_val_inc, %bb2]
//    ptr_val2 = IntToPtr(int_val)
//    ...
//    use(ptr_val2)
//    ptr_val_inc = ...
//    inc_val_inc = PtrToInt(ptr_val_inc)
//
// ==>
// bb1:
//     br label %bb2
// bb2:
//    ptr_val = PHI([ptr_init, %bb1], [ptr_val_inc, %bb2]
//    ...
//    use(ptr_val)
//    ptr_val_inc = ...
//
// Case-2:
// bb1:
//    int_ptr = BitCast(ptr_ptr)
//    int_init = Load(int_ptr)
//    br label %bb2
// bb2:
//    int_val = PHI([int_init, %bb1], [int_val_inc, %bb2]
//    ptr_val2 = IntToPtr(int_val)
//    ...
//    use(ptr_val2)
//    ptr_val_inc = ...
//    inc_val_inc = PtrToInt(ptr_val_inc)
// ==>
// bb1:
//    ptr_init = Load(ptr_ptr)
//    br label %bb2
// bb2:
//    ptr_val = PHI([ptr_init, %bb1], [ptr_val_inc, %bb2]
//    ...
//    use(ptr_val)
//    ptr_val_inc = ...
//    ...
//
bool InstCombinerImpl::foldIntegerTypedPHI(PHINode &PN) {}

// Remove RoundTrip IntToPtr/PtrToInt Cast on PHI-Operand and
// fold Phi-operand to bitcast.
Instruction *InstCombinerImpl::foldPHIArgIntToPtrToPHI(PHINode &PN) {}

/// If we have something like phi [insertvalue(a,b,0), insertvalue(c,d,0)],
/// turn this into a phi[a,c] and phi[b,d] and a single insertvalue.
Instruction *
InstCombinerImpl::foldPHIArgInsertValueInstructionIntoPHI(PHINode &PN) {}

/// If we have something like phi [extractvalue(a,0), extractvalue(b,0)],
/// turn this into a phi[a,b] and a single extractvalue.
Instruction *
InstCombinerImpl::foldPHIArgExtractValueInstructionIntoPHI(PHINode &PN) {}

/// If we have something like phi [add (a,b), add(a,c)] and if a/b/c and the
/// adds all have a single user, turn this into a phi and a single binop.
Instruction *InstCombinerImpl::foldPHIArgBinOpIntoPHI(PHINode &PN) {}

Instruction *InstCombinerImpl::foldPHIArgGEPIntoPHI(PHINode &PN) {}

/// Return true if we know that it is safe to sink the load out of the block
/// that defines it. This means that it must be obvious the value of the load is
/// not changed from the point of the load to the end of the block it is in.
///
/// Finally, it is safe, but not profitable, to sink a load targeting a
/// non-address-taken alloca.  Doing so will cause us to not promote the alloca
/// to a register.
static bool isSafeAndProfitableToSinkLoad(LoadInst *L) {}

Instruction *InstCombinerImpl::foldPHIArgLoadIntoPHI(PHINode &PN) {}

/// TODO: This function could handle other cast types, but then it might
/// require special-casing a cast from the 'i1' type. See the comment in
/// FoldPHIArgOpIntoPHI() about pessimizing illegal integer types.
Instruction *InstCombinerImpl::foldPHIArgZextsIntoPHI(PHINode &Phi) {}

/// If all operands to a PHI node are the same "unary" operator and they all are
/// only used by the PHI, PHI together their inputs, and do the operation once,
/// to the result of the PHI.
Instruction *InstCombinerImpl::foldPHIArgOpIntoPHI(PHINode &PN) {}

/// Return true if this phi node is always equal to NonPhiInVal.
/// This happens with mutually cyclic phi nodes like:
///   z = some value; x = phi (y, z); y = phi (x, z)
static bool PHIsEqualValue(PHINode *PN, Value *&NonPhiInVal,
                           SmallPtrSetImpl<PHINode *> &ValueEqualPHIs) {}

/// Return an existing non-zero constant if this phi node has one, otherwise
/// return constant 1.
static ConstantInt *getAnyNonZeroConstInt(PHINode &PN) {}

namespace {
struct PHIUsageRecord {};

struct LoweredPHIRecord {};
} // namespace

namespace llvm {
  template<>
  struct DenseMapInfo<LoweredPHIRecord> {};
} // namespace llvm


/// This is an integer PHI and we know that it has an illegal type: see if it is
/// only used by trunc or trunc(lshr) operations. If so, we split the PHI into
/// the various pieces being extracted. This sort of thing is introduced when
/// SROA promotes an aggregate to large integer values.
///
/// TODO: The user of the trunc may be an bitcast to float/double/vector or an
/// inttoptr.  We should produce new PHIs in the right type.
///
Instruction *InstCombinerImpl::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) {}

static Value *simplifyUsingControlFlow(InstCombiner &Self, PHINode &PN,
                                       const DominatorTree &DT) {}

// Fold  iv = phi(start, iv.next = iv2.next op start)
// where iv2 = phi(iv2.start, iv2.next = iv2 + iv2.step)
// and   iv2.start op start = start
// to    iv = iv2 op start
static Value *foldDependentIVs(PHINode &PN, IRBuilderBase &Builder) {}

// PHINode simplification
//
Instruction *InstCombinerImpl::visitPHINode(PHINode &PN) {}