liberty/lib/Utilities/InlineFunctionWithVmap.cpp
/// HandleByValArgument - When inlining a call site that has a byval argument,
/// we have to make the implicit memcpy explicit by adding it.
When inlining a call site that has a byval argument,
we have to make the implicit memcpy explicit by adding it.
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) {
  Type *AggTy = cast<PointerType>(Arg->getType())->getElementType();
  Function *Caller = TheCall->getFunction();
  const DataLayout &DL = Caller->getParent()->getDataLayout();
  if (CalledFunc->onlyReadsMemory()) {
    if (ByValAlignment <= 1)  
      return Arg;
    AssumptionCache *AC =
        IFI.GetAssumptionCache ? &(*IFI.GetAssumptionCache)(*Caller) : nullptr;
    if (getOrEnforceKnownAlignment(Arg, ByValAlignment, DL, TheCall, AC) >=
        ByValAlignment)
      return Arg;
  }
  unsigned Align = DL.getPrefTypeAlignment(AggTy);
  Align = std::max(Align, ByValAlignment);
  Value *NewAlloca = new AllocaInst(AggTy, DL.getAllocaAddrSpace(),
                                    nullptr, Align, Arg->getName(),
                                    &*Caller->begin()->begin());
  IFI.StaticAllocas.push_back(cast<AllocaInst>(NewAlloca));
  return NewAlloca;
}
static Value * HandleByValArgument ( Value * Arg , Instruction * TheCall , const Function * CalledFunc , InlineFunctionInfo & IFI , unsigned ByValAlignment ) { Type * AggTy = cast < PointerType > ( Arg -> getType ( ) ) -> getElementType ( ) ; Function * Caller = TheCall -> getFunction ( ) ; const DataLayout & DL = Caller -> getParent ( ) -> getDataLayout ( ) ; if ( CalledFunc -> onlyReadsMemory ( ) ) { if ( ByValAlignment <= 1 ) return Arg ; AssumptionCache * AC = IFI . GetAssumptionCache ? & ( * IFI . GetAssumptionCache ) ( * Caller ) : nullptr ; if ( getOrEnforceKnownAlignment ( Arg , ByValAlignment , DL , TheCall , AC ) >= ByValAlignment ) return Arg ; } unsigned Align = DL . getPrefTypeAlignment ( AggTy ) ; Align = std :: max ( Align , ByValAlignment ) ; Value * NewAlloca = new AllocaInst ( AggTy , DL . getAllocaAddrSpace ( ) , nullptr , Align , Arg -> getName ( ) , & * Caller -> begin ( ) -> begin ( ) ) ; IFI . StaticAllocas . push_back ( cast < AllocaInst > ( NewAlloca ) ) ; return NewAlloca ; }
HandleByValArgument - When inlining a call site that has a byval argument,
we have to make the implicit memcpy explicit by adding it.
HandleByValArgument - When inlining a call site that has a byval argument we have to make the implicit memcpy explicit by adding it .
// 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 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. // 0 = unspecified, 1 = no particular alignment. // 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. // 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. // Create the alloca.  If we have DataLayout, use nice alignment. // 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). // Uses of the argument in the function should use our new alloca // instead.