Example #1
0
/// Parse a tuple pattern.
///
///   pattern-tuple:
///     '(' pattern-tuple-body? ')'
///   pattern-tuple-body:
///     pattern-tuple-element (',' pattern-tuple-body)*
ParserResult<Pattern> Parser::parsePatternTuple() {
  StructureMarkerRAII ParsingPatternTuple(*this, Tok);
  SourceLoc LPLoc = consumeToken(tok::l_paren);
  SourceLoc RPLoc;

  // Parse all the elements.
  SmallVector<TuplePatternElt, 8> elts;
  ParserStatus ListStatus =
    parseList(tok::r_paren, LPLoc, RPLoc, tok::comma, /*OptionalSep=*/false,
              /*AllowSepAfterLast=*/false,
              diag::expected_rparen_tuple_pattern_list,
              [&] () -> ParserStatus {
    // Parse the pattern tuple element.
    ParserStatus EltStatus;
    Optional<TuplePatternElt> elt;
    std::tie(EltStatus, elt) = parsePatternTupleElement();
    if (EltStatus.hasCodeCompletion())
      return makeParserCodeCompletionStatus();
    if (!elt)
      return makeParserError();

    // Add this element to the list.
    elts.push_back(*elt);
    return makeParserSuccess();
  });

  return makeParserResult(
           ListStatus,
           TuplePattern::createSimple(Context, LPLoc, elts, RPLoc));
}
Example #2
0
/// Clone the given generic parameters in the given list. We don't need any
/// of the requirements, because they will be inferred.
static GenericParamList *cloneGenericParams(ASTContext &ctx,
                                            DeclContext *dc,
                                            GenericParamList *fromParams) {
  // Clone generic parameters.
  SmallVector<GenericTypeParamDecl *, 2> toGenericParams;
  for (auto fromGP : *fromParams) {
    // Create the new generic parameter.
    auto toGP = new (ctx) GenericTypeParamDecl(dc, fromGP->getName(),
                                               SourceLoc(),
                                               fromGP->getDepth(),
                                               fromGP->getIndex());
    toGP->setImplicit(true);

    // Record new generic parameter.
    toGenericParams.push_back(toGP);
  }

  auto toParams = GenericParamList::create(ctx, SourceLoc(), toGenericParams,
                                           SourceLoc());

  auto outerParams = fromParams->getOuterParameters();
  if (outerParams != nullptr)
    outerParams = cloneGenericParams(ctx, dc, outerParams);
  toParams->setOuterParameters(outerParams);

  return toParams;
}
Example #3
0
static bool deduceFunctionAttributeInRPO(Module &M, CallGraph &CG) {
  // We only have a post-order SCC traversal (because SCCs are inherently
  // discovered in post-order), so we accumulate them in a vector and then walk
  // it in reverse. This is simpler than using the RPO iterator infrastructure
  // because we need to combine SCC detection and the PO walk of the call
  // graph. We can also cheat egregiously because we're primarily interested in
  // synthesizing norecurse and so we can only save the singular SCCs as SCCs
  // with multiple functions in them will clearly be recursive.
  SmallVector<Function *, 16> Worklist;
  for (scc_iterator<CallGraph *> I = scc_begin(&CG); !I.isAtEnd(); ++I) {
    if (I->size() != 1)
      continue;

    Function *F = I->front()->getFunction();
    if (F && !F->isDeclaration() && !F->doesNotRecurse() &&
        F->hasInternalLinkage())
      Worklist.push_back(F);
  }

  bool Changed = false;
  for (auto *F : reverse(Worklist))
    Changed |= addNoRecurseAttrsTopDown(*F);

  return Changed;
}
Example #4
0
bool RecurrenceDescriptor::getSourceExtensionKind(
    Instruction *Start, Instruction *Exit, Type *RT, bool &IsSigned,
    SmallPtrSetImpl<Instruction *> &Visited,
    SmallPtrSetImpl<Instruction *> &CI) {

  SmallVector<Instruction *, 8> Worklist;
  bool FoundOneOperand = false;
  unsigned DstSize = RT->getPrimitiveSizeInBits();
  Worklist.push_back(Exit);

  // Traverse the instructions in the reduction expression, beginning with the
  // exit value.
  while (!Worklist.empty()) {
    Instruction *I = Worklist.pop_back_val();
    for (Use &U : I->operands()) {

      // Terminate the traversal if the operand is not an instruction, or we
      // reach the starting value.
      Instruction *J = dyn_cast<Instruction>(U.get());
      if (!J || J == Start)
        continue;

      // Otherwise, investigate the operation if it is also in the expression.
      if (Visited.count(J)) {
        Worklist.push_back(J);
        continue;
      }

      // If the operand is not in Visited, it is not a reduction operation, but
      // it does feed into one. Make sure it is either a single-use sign- or
      // zero-extend instruction.
      CastInst *Cast = dyn_cast<CastInst>(J);
      bool IsSExtInst = isa<SExtInst>(J);
      if (!Cast || !Cast->hasOneUse() || !(isa<ZExtInst>(J) || IsSExtInst))
        return false;

      // Ensure the source type of the extend is no larger than the reduction
      // type. It is not necessary for the types to be identical.
      unsigned SrcSize = Cast->getSrcTy()->getPrimitiveSizeInBits();
      if (SrcSize > DstSize)
        return false;

      // Furthermore, ensure that all such extends are of the same kind.
      if (FoundOneOperand) {
        if (IsSigned != IsSExtInst)
          return false;
      } else {
        FoundOneOperand = true;
        IsSigned = IsSExtInst;
      }

      // Lastly, if the source type of the extend matches the reduction type,
      // add the extend to CI so that we can avoid accounting for it in the
      // cost model.
      if (SrcSize == DstSize)
        CI.insert(Cast);
    }
  }
  return true;
}
Example #5
0
bool CallLowering::lowerCall(
    MachineIRBuilder &MIRBuilder, ImmutableCallSite CS, unsigned ResReg,
    ArrayRef<unsigned> ArgRegs, std::function<unsigned()> GetCalleeReg) const {
  auto &DL = CS.getParent()->getParent()->getParent()->getDataLayout();

  // First step is to marshall all the function's parameters into the correct
  // physregs and memory locations. Gather the sequence of argument types that
  // we'll pass to the assigner function.
  SmallVector<ArgInfo, 8> OrigArgs;
  unsigned i = 0;
  unsigned NumFixedArgs = CS.getFunctionType()->getNumParams();
  for (auto &Arg : CS.args()) {
    ArgInfo OrigArg{ArgRegs[i], Arg->getType(), ISD::ArgFlagsTy{},
                    i < NumFixedArgs};
    setArgFlags(OrigArg, i + AttributeList::FirstArgIndex, DL, CS);
    // We don't currently support swifterror or swiftself args.
    if (OrigArg.Flags.isSwiftError() || OrigArg.Flags.isSwiftSelf())
      return false;
    OrigArgs.push_back(OrigArg);
    ++i;
  }

  MachineOperand Callee = MachineOperand::CreateImm(0);
  if (const Function *F = CS.getCalledFunction())
    Callee = MachineOperand::CreateGA(F, 0);
  else
    Callee = MachineOperand::CreateReg(GetCalleeReg(), false);

  ArgInfo OrigRet{ResReg, CS.getType(), ISD::ArgFlagsTy{}};
  if (!OrigRet.Ty->isVoidTy())
    setArgFlags(OrigRet, AttributeList::ReturnIndex, DL, CS);

  return lowerCall(MIRBuilder, CS.getCallingConv(), Callee, OrigRet, OrigArgs);
}
void WebAssemblyAsmPrinter::EmitFunctionBodyStart() {
  getTargetStreamer()->emitParam(CurrentFnSym, MFI->getParams());

  SmallVector<MVT, 4> ResultVTs;
  const Function &F = MF->getFunction();

  // Emit the function index.
  if (MDNode *Idx = F.getMetadata("wasm.index")) {
    assert(Idx->getNumOperands() == 1);

    getTargetStreamer()->emitIndIdx(AsmPrinter::lowerConstant(
        cast<ConstantAsMetadata>(Idx->getOperand(0))->getValue()));
  }

  ComputeLegalValueVTs(F, TM, F.getReturnType(), ResultVTs);

  // If the return type needs to be legalized it will get converted into
  // passing a pointer.
  if (ResultVTs.size() == 1)
    getTargetStreamer()->emitResult(CurrentFnSym, ResultVTs);
  else
    getTargetStreamer()->emitResult(CurrentFnSym, ArrayRef<MVT>());

  getTargetStreamer()->emitLocal(MFI->getLocals());

  AsmPrinter::EmitFunctionBodyStart();
}
Example #7
0
SmallVector<ProtocolDecl *, 2>
DeclContext::getLocalProtocols(
  ConformanceLookupKind lookupKind,
  SmallVectorImpl<ConformanceDiagnostic> *diagnostics,
  bool sorted) const
{
  SmallVector<ProtocolDecl *, 2> result;

  // Dig out the nominal type.
  NominalTypeDecl *nominal = getAsNominalTypeOrNominalTypeExtensionContext();
  if (!nominal)
    return result;

  // Update to record all potential conformances.
  nominal->prepareConformanceTable();
  nominal->ConformanceTable->lookupConformances(
    nominal,
    const_cast<DeclContext *>(this),
    getASTContext().getLazyResolver(),
    lookupKind,
    &result,
    nullptr,
    diagnostics);

  // Sort if required.
  if (sorted) {
    llvm::array_pod_sort(result.begin(), result.end(),
                         &ProtocolType::compareProtocols);
  }

  return result;
}
Example #8
0
static bool sinkFixLifetime(SILLoop *Loop, DominanceInfo *DomTree,
                            SILLoopInfo *LI) {
  DEBUG(llvm::errs() << " Sink fix_lifetime attempt\n");
  auto Preheader = Loop->getLoopPreheader();
  if (!Preheader)
    return false;

  // Only handle innermost loops for now.
  if (!Loop->getSubLoops().empty())
    return false;

  // Only handle single exit blocks for now.
  auto *ExitBB = Loop->getExitBlock();
  if (!ExitBB)
    return false;
  auto *ExitingBB = Loop->getExitingBlock();
  if (!ExitingBB)
    return false;

  // We can sink fix_lifetime instructions if there are no reference counting
  // instructions in the loop.
  SmallVector<FixLifetimeInst *, 16> FixLifetimeInsts;
  for (auto *BB : Loop->getBlocks()) {
    for (auto &Inst : *BB) {
      if (auto FLI = dyn_cast<FixLifetimeInst>(&Inst)) {
        FixLifetimeInsts.push_back(FLI);
      } else if (Inst.mayHaveSideEffects() && !isa<LoadInst>(&Inst) &&
                 !isa<StoreInst>(&Inst)) {
        DEBUG(llvm::errs() << "  mayhavesideeffects because of" << Inst);
        DEBUG(Inst.getParent()->dump());
        return false;
      }
    }
  }

  // Sink the fix_lifetime instruction.
  bool Changed = false;
  for (auto *FLI : FixLifetimeInsts)
    if (DomTree->dominates(FLI->getOperand()->getParentBlock(),
                           Preheader)) {
      auto Succs = ExitingBB->getSuccessors();
      for (unsigned EdgeIdx = 0; EdgeIdx <  Succs.size(); ++EdgeIdx) {
        SILBasicBlock *BB = Succs[EdgeIdx];
        if (BB == ExitBB) {
          auto *SplitBB = splitCriticalEdge(ExitingBB->getTerminator(), EdgeIdx,
                                            DomTree, LI);
          auto *OutsideBB = SplitBB ? SplitBB : ExitBB;
          // Update the ExitBB.
          ExitBB = OutsideBB;
          DEBUG(llvm::errs() << "  moving fix_lifetime to exit BB " << *FLI);
          FLI->moveBefore(&*OutsideBB->begin());
          Changed = true;
        }
      }
    } else {
      DEBUG(llvm::errs() << "  does not dominate " << *FLI);
    }

  return Changed;
}
Example #9
0
BasicBlock *Loop::getUniqueExitBlock() const {
  SmallVector<BasicBlock *, 8> UniqueExitBlocks;
  getUniqueExitBlocks(UniqueExitBlocks);
  if (UniqueExitBlocks.size() == 1)
    return UniqueExitBlocks[0];
  return nullptr;
}
Example #10
0
static SmallString<256> remove_dots(StringRef path, bool remove_dot_dot,
                                    Style style) {
  SmallVector<StringRef, 16> components;

  // Skip the root path, then look for traversal in the components.
  StringRef rel = path::relative_path(path, style);
  for (StringRef C :
       llvm::make_range(path::begin(rel, style), path::end(rel))) {
    if (C == ".")
      continue;
    // Leading ".." will remain in the path unless it's at the root.
    if (remove_dot_dot && C == "..") {
      if (!components.empty() && components.back() != "..") {
        components.pop_back();
        continue;
      }
      if (path::is_absolute(path, style))
        continue;
    }
    components.push_back(C);
  }

  SmallString<256> buffer = path::root_path(path, style);
  for (StringRef C : components)
    path::append(buffer, style, C);
  return buffer;
}
Example #11
0
/// Checks if a generic callee and caller have compatible layout constraints.
static bool isCallerAndCalleeLayoutConstraintsCompatible(FullApplySite AI) {
  SILFunction *Callee = AI.getReferencedFunction();
  auto CalleeSig = Callee->getLoweredFunctionType()->getGenericSignature();
  auto AISubs = AI.getSubstitutionMap();

  SmallVector<GenericTypeParamType *, 4> SubstParams;
  CalleeSig->forEachParam([&](GenericTypeParamType *Param, bool Canonical) {
    if (Canonical)
      SubstParams.push_back(Param);
  });

  for (auto Param : SubstParams) {
    // Map the parameter into context
    auto ContextTy = Callee->mapTypeIntoContext(Param->getCanonicalType());
    auto Archetype = ContextTy->getAs<ArchetypeType>();
    if (!Archetype)
      continue;
    auto Layout = Archetype->getLayoutConstraint();
    if (!Layout)
      continue;
    // The generic parameter has a layout constraint.
    // Check that the substitution has the same constraint.
    auto AIReplacement = Type(Param).subst(AISubs);
    auto AIArchetype = AIReplacement->getAs<ArchetypeType>();
    if (!AIArchetype)
      return false;
    auto AILayout = AIArchetype->getLayoutConstraint();
    if (!AILayout)
      return false;
    if (AILayout != Layout)
      return false;
  }
  return true;
}
Example #12
0
Metadata *llvm::MapMetadata(const Metadata *MD, ValueToValueMapTy &VM,
                            RemapFlags Flags, ValueMapTypeRemapper *TypeMapper,
                            ValueMaterializer *Materializer) {
  SmallVector<MDNode *, 8> DistinctWorklist;
  Metadata *NewMD = MapMetadataImpl(MD, DistinctWorklist, VM, Flags, TypeMapper,
                                    Materializer);

  // When there are no module-level changes, it's possible that the metadata
  // graph has temporaries.  Skip the logic to resolve cycles, since it's
  // unnecessary (and invalid) in that case.
  if (Flags & RF_NoModuleLevelChanges)
    return NewMD;

  // If the top-level metadata was a uniqued MDNode, it could be involved in a
  // uniquing cycle.
  if (auto *N = dyn_cast<MDNode>(NewMD))
    if (!N->isResolved())
      N->resolveCycles();

  // Remap the operands of distinct MDNodes.
  while (!DistinctWorklist.empty()) {
    auto *N = DistinctWorklist.pop_back_val();

    // If an operand changes, then it may be involved in a uniquing cycle.
    if (remapOperands(*N, DistinctWorklist, VM, Flags, TypeMapper,
                      Materializer))
      for (Metadata *MD : N->operands())
        if (auto *Op = dyn_cast_or_null<MDNode>(MD))
          if (!Op->isResolved())
            Op->resolveCycles();
  }

  return NewMD;
}
Example #13
0
void RecordInfo::walkBases() {
  // This traversal is akin to CXXRecordDecl::forallBases()'s,
  // but without stepping over dependent bases -- these might also
  // have a "GC base name", so are to be included and considered.
  SmallVector<const CXXRecordDecl*, 8> queue;

  const CXXRecordDecl* base_record = record();
  while (true) {
    for (const auto& it : base_record->bases()) {
      const RecordType* type = it.getType()->getAs<RecordType>();
      CXXRecordDecl* base;
      if (!type)
        base = GetDependentTemplatedDecl(*it.getType());
      else {
        base = cast_or_null<CXXRecordDecl>(type->getDecl()->getDefinition());
        if (base)
          queue.push_back(base);
      }
      if (!base)
        continue;

      const std::string& name = base->getName();
      if (Config::IsGCBase(name)) {
        gc_base_names_.push_back(name);
        is_gc_derived_ = true;
      }
    }

    if (queue.empty())
      break;
    base_record = queue.pop_back_val(); // not actually a queue.
  }
}
Example #14
0
void XRayInstrumentation::replaceRetWithPatchableRet(MachineFunction &MF,
        const TargetInstrInfo *TII)
{
    // We look for *all* terminators and returns, then replace those with
    // PATCHABLE_RET instructions.
    SmallVector<MachineInstr *, 4> Terminators;
    for (auto &MBB : MF) {
        for (auto &T : MBB.terminators()) {
            unsigned Opc = 0;
            if (T.isReturn() && T.getOpcode() == TII->getReturnOpcode()) {
                // Replace return instructions with:
                //   PATCHABLE_RET <Opcode>, <Operand>...
                Opc = TargetOpcode::PATCHABLE_RET;
            }
            if (TII->isTailCall(T)) {
                // Treat the tail call as a return instruction, which has a
                // different-looking sled than the normal return case.
                Opc = TargetOpcode::PATCHABLE_TAIL_CALL;
            }
            if (Opc != 0) {
                auto MIB = BuildMI(MBB, T, T.getDebugLoc(), TII->get(Opc))
                           .addImm(T.getOpcode());
                for (auto &MO : T.operands())
                    MIB.addOperand(MO);
                Terminators.push_back(&T);
            }
        }
    }

    for (auto &I : Terminators)
        I->eraseFromParent();
}
Example #15
0
DILocation *DILocation::getImpl(LLVMContext &Context, unsigned Line,
                                unsigned Column, Metadata *Scope,
                                Metadata *InlinedAt, StorageType Storage,
                                bool ShouldCreate) {
  // Fixup column.
  adjustColumn(Column);

  if (Storage == Uniqued) {
    if (auto *N =
            getUniqued(Context.pImpl->DILocations,
                       DILocationInfo::KeyTy(Line, Column, Scope, InlinedAt)))
      return N;
    if (!ShouldCreate)
      return nullptr;
  } else {
    assert(ShouldCreate && "Expected non-uniqued nodes to always be created");
  }

  SmallVector<Metadata *, 2> Ops;
  Ops.push_back(Scope);
  if (InlinedAt)
    Ops.push_back(InlinedAt);
  return storeImpl(new (Ops.size())
                       DILocation(Context, Storage, Line, Column, Ops),
                   Storage, Context.pImpl->DILocations);
}
Example #16
0
bool MachOLinkingContext::parsePackedVersion(StringRef str, uint32_t &result) {
    result = 0;

    if (str.empty())
        return false;

    SmallVector<StringRef, 3> parts;
    llvm::SplitString(str, parts, ".");

    unsigned long long num;
    if (llvm::getAsUnsignedInteger(parts[0], 10, num))
        return true;
    if (num > 65535)
        return true;
    result = num << 16;

    if (parts.size() > 1) {
        if (llvm::getAsUnsignedInteger(parts[1], 10, num))
            return true;
        if (num > 255)
            return true;
        result |= (num << 8);
    }

    if (parts.size() > 2) {
        if (llvm::getAsUnsignedInteger(parts[2], 10, num))
            return true;
        if (num > 255)
            return true;
        result |= num;
    }

    return false;
}
Example #17
0
DISubprogram *DISubprogram::getImpl(
    LLVMContext &Context, Metadata *Scope, MDString *Name,
    MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
    bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine,
    Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex,
    int ThisAdjustment, DIFlags Flags, bool IsOptimized, Metadata *Unit,
    Metadata *TemplateParams, Metadata *Declaration, Metadata *Variables,
    Metadata *ThrownTypes, StorageType Storage, bool ShouldCreate) {
  assert(isCanonical(Name) && "Expected canonical MDString");
  assert(isCanonical(LinkageName) && "Expected canonical MDString");
  DEFINE_GETIMPL_LOOKUP(
      DISubprogram, (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
                     IsDefinition, ScopeLine, ContainingType, Virtuality,
                     VirtualIndex, ThisAdjustment, Flags, IsOptimized, Unit,
                     TemplateParams, Declaration, Variables, ThrownTypes));
  SmallVector<Metadata *, 11> Ops = {
      File,        Scope,     Name,           LinkageName,    Type,       Unit,
      Declaration, Variables, ContainingType, TemplateParams, ThrownTypes};
  if (!ThrownTypes) {
    Ops.pop_back();
    if (!TemplateParams) {
      Ops.pop_back();
      if (!ContainingType)
        Ops.pop_back();
    }
  }
  DEFINE_GETIMPL_STORE_N(DISubprogram,
                         (Line, ScopeLine, Virtuality, VirtualIndex,
                          ThisAdjustment, Flags, IsLocalToUnit, IsDefinition,
                          IsOptimized),
                         Ops, Ops.size());
}
Example #18
0
void IRGenModule::
emitAssociatedTypeMetadataRecord(const ProtocolConformance *Conformance) {
  if (!IRGen.Opts.EnableReflectionMetadata)
    return;

  SmallVector<std::pair<StringRef, CanType>, 2> AssociatedTypes;

  auto collectTypeWitness = [&](const AssociatedTypeDecl *AssocTy,
                                const Substitution &Sub,
                                const TypeDecl *TD) -> bool {

    auto Subst = ArchetypeBuilder::mapTypeOutOfContext(
      Conformance->getDeclContext(), Sub.getReplacement());

    AssociatedTypes.push_back({
      AssocTy->getNameStr(),
      Subst->getCanonicalType()
    });
    return false;
  };

  Conformance->forEachTypeWitness(/*resolver*/ nullptr, collectTypeWitness);

  // If there are no associated types, don't bother emitting any
  // metadata.
  if (AssociatedTypes.empty())
    return;

  AssociatedTypeMetadataBuilder builder(*this, Conformance, AssociatedTypes);
  auto var = builder.emit();
  if (var)
    addUsedGlobal(var);
}
Example #19
0
/// \brief Removes instructions that create the callee value if they are no
/// longer necessary after inlining.
static void cleanupCalleeValue(
    SILValue CalleeValue,
    ArrayRef<SILValue> FullArgs) {
  SmallVector<SILInstruction*, 16> InstsToDelete;
  for (SILValue V : FullArgs) {
    if (V != CalleeValue)
      if (auto *I = V->getDefiningInstruction())
        if (isInstructionTriviallyDead(I))
          InstsToDelete.push_back(I);
  }
  recursivelyDeleteTriviallyDeadInstructions(InstsToDelete, true);

  // Handle the case where the callee of the apply is a load instruction. If we
  // fail to optimize, return. Otherwise, see if we can look through other
  // abstractions on our callee.
  if (auto *LI = dyn_cast<LoadInst>(CalleeValue)) {
    CalleeValue = cleanupLoadedCalleeValue(CalleeValue, LI);
    if (!CalleeValue) {
      return;
    }
  }

  SILValue CalleeSource = CalleeValue;
  // Handle partial_apply/thin_to_thick -> convert_function:
  // tryDeleteDeadClosure must run before deleting a ConvertFunction that
  // uses the PartialApplyInst or ThinToThickFunctionInst. tryDeleteDeadClosure
  // will delete any uses of the closure, including a convert_escape_to_noescape
  // conversion.
  if (auto *CFI = dyn_cast<ConvertFunctionInst>(CalleeValue))
    CalleeSource = CFI->getOperand();
  else if (auto *Cvt = dyn_cast<ConvertEscapeToNoEscapeInst>(CalleeValue))
    CalleeSource = Cvt->getOperand();

  if (auto *PAI = dyn_cast<PartialApplyInst>(CalleeSource)) {
    SILValue Callee = PAI->getCallee();
    if (!tryDeleteDeadClosure(PAI))
      return;
    CalleeValue = Callee;

  } else if (auto *TTTFI = dyn_cast<ThinToThickFunctionInst>(CalleeSource)) {
    SILValue Callee = TTTFI->getCallee();
    if (!tryDeleteDeadClosure(TTTFI))
      return;
    CalleeValue = Callee;
  }

  // Handle function_ref -> convert_function -> partial_apply/thin_to_thick.
  if (auto *CFI = dyn_cast<ConvertFunctionInst>(CalleeValue)) {
    if (isInstructionTriviallyDead(CFI)) {
      recursivelyDeleteTriviallyDeadInstructions(CFI, true);
      return;
    }
  }

  if (auto *FRI = dyn_cast<FunctionRefInst>(CalleeValue)) {
    if (!FRI->use_empty())
      return;
    FRI->eraseFromParent();
  }
}
Example #20
0
bool GlobalModuleIndex::lookupIdentifier(StringRef Name, HitSet &Hits) {
  Hits.clear();
  
  // If there's no identifier index, there is nothing we can do.
  if (!IdentifierIndex)
    return false;

  // Look into the identifier index.
  ++NumIdentifierLookups;
  IdentifierIndexTable &Table
    = *static_cast<IdentifierIndexTable *>(IdentifierIndex);
  IdentifierIndexTable::iterator Known = Table.find(Name);
  if (Known == Table.end()) {
    return true;
  }

  SmallVector<unsigned, 2> ModuleIDs = *Known;
  for (unsigned I = 0, N = ModuleIDs.size(); I != N; ++I) {
    unsigned ID = ModuleIDs[I];
    if (ID >= Modules.size() || !Modules[ID].File)
      continue;

    Hits.insert(Modules[ID].File);
  }

  ++NumIdentifierLookupHits;
  return true;
}
Example #21
0
RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
  if (Common)
    return Common;

  // Walk the previous-declaration chain until we either find a declaration
  // with a common pointer or we run out of previous declarations.
  SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
  for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
       Prev = Prev->getPreviousDecl()) {
    if (Prev->Common) {
      Common = Prev->Common;
      break;
    }

    PrevDecls.push_back(Prev);
  }

  // If we never found a common pointer, allocate one now.
  if (!Common) {
    // FIXME: If any of the declarations is from an AST file, we probably
    // need an update record to add the common data.

    Common = newCommon(getASTContext());
  }

  // Update any previous declarations we saw with the common pointer.
  for (unsigned I = 0, N = PrevDecls.size(); I != N; ++I)
    PrevDecls[I]->Common = Common;

  return Common;
}
Example #22
0
/// A helper function to check if the current ranges are all inside the same
/// macro argument expansion as Loc.
static bool checkRangesForMacroArgExpansion(SourceLocation Loc,
                                            ArrayRef<CharSourceRange> Ranges,
                                            const SourceManager &SM) {
  assert(Loc.isMacroID() && "Must be a macro expansion!");

  SmallVector<CharSourceRange, 4> SpellingRanges;
  mapDiagnosticRanges(Loc, Ranges, SpellingRanges, &SM);

  /// Count all valid ranges.
  unsigned ValidCount = 0;
  for (auto I : Ranges)
    if (I.isValid()) ValidCount++;

  if (ValidCount > SpellingRanges.size())
    return false;

  /// To store the source location of the argument location.
  SourceLocation ArgumentLoc;

  /// Set the ArgumentLoc to the beginning location of the expansion of Loc
  /// so to check if the ranges expands to the same beginning location.
  if (!SM.isMacroArgExpansion(Loc,&ArgumentLoc))
    return false;

  for (auto I = SpellingRanges.begin(), E = SpellingRanges.end(); I != E; ++I) {
    if (!checkRangeForMacroArgExpansion(*I, SM, ArgumentLoc))
      return false;
  }

  return true;
}
Example #23
0
CXCursor cxcursor::MakeCXCursor(const Decl *D, CXTranslationUnit TU,
                                SourceRange RegionOfInterest,
                                bool FirstInDeclGroup) {
    assert(D && TU && "Invalid arguments!");

    CXCursorKind K = getCursorKindForDecl(D);

    if (K == CXCursor_ObjCClassMethodDecl ||
            K == CXCursor_ObjCInstanceMethodDecl) {
        int SelectorIdIndex = -1;
        // Check if cursor points to a selector id.
        if (RegionOfInterest.isValid() &&
                RegionOfInterest.getBegin() == RegionOfInterest.getEnd()) {
            SmallVector<SourceLocation, 16> SelLocs;
            cast<ObjCMethodDecl>(D)->getSelectorLocs(SelLocs);
            SmallVectorImpl<SourceLocation>::iterator
            I=std::find(SelLocs.begin(), SelLocs.end(),RegionOfInterest.getBegin());
            if (I != SelLocs.end())
                SelectorIdIndex = I - SelLocs.begin();
        }
        CXCursor C = { K, SelectorIdIndex,
            { D, (void*)(intptr_t) (FirstInDeclGroup ? 1 : 0), TU }
        };
        return C;
    }

    CXCursor C = { K, 0, { D, (void*)(intptr_t) (FirstInDeclGroup ? 1 : 0), TU }};
    return C;
}
/// Returns a generated guard statement that checks whether the given lhs and
/// rhs expressions are equal. If not equal, the else block for the guard
/// returns false.
/// \p C The AST context.
/// \p lhsExpr The first expression to compare for equality.
/// \p rhsExpr The second expression to compare for equality.
static GuardStmt *returnIfNotEqualGuard(ASTContext &C,
                                        Expr *lhsExpr,
                                        Expr *rhsExpr) {
  SmallVector<StmtConditionElement, 1> conditions;
  SmallVector<ASTNode, 1> statements;

  // First, generate the statement for the body of the guard.
  // return false
  auto falseExpr = new (C) BooleanLiteralExpr(false, SourceLoc(),
                                              /*Implicit*/true);
  auto returnStmt = new (C) ReturnStmt(SourceLoc(), falseExpr);
  statements.emplace_back(ASTNode(returnStmt));

  // Next, generate the condition being checked.
  // lhs == rhs
  auto cmpFuncExpr = new (C) UnresolvedDeclRefExpr(
    DeclName(C.getIdentifier("==")), DeclRefKind::BinaryOperator,
    DeclNameLoc());
  auto cmpArgsTuple = TupleExpr::create(C, SourceLoc(),
                                        { lhsExpr, rhsExpr },
                                        { }, { }, SourceLoc(),
                                        /*HasTrailingClosure*/false,
                                        /*Implicit*/true);
  auto cmpExpr = new (C) BinaryExpr(cmpFuncExpr, cmpArgsTuple,
                                    /*Implicit*/true);
  conditions.emplace_back(cmpExpr);

  // Build and return the complete guard statement.
  // guard lhs == rhs else { return false }
  auto body = BraceStmt::create(C, SourceLoc(), statements, SourceLoc());
  return new (C) GuardStmt(SourceLoc(), C.AllocateCopy(conditions), body);
}
static void replaceFrameIndexes(MachineFunction &MF, 
                                SmallVector<std::pair<int,int64_t>, 16> &FR) {
  MachineFrameInfo *MFI = MF.getFrameInfo();
  MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
  const SmallVector<std::pair<int,int64_t>, 16>::iterator FRB = FR.begin();
  const SmallVector<std::pair<int,int64_t>, 16>::iterator FRE = FR.end();

  SmallVector<std::pair<int,int64_t>, 16>::iterator FRI = FRB;
  for (; FRI != FRE; ++FRI) {
    MFI->RemoveStackObject(FRI->first);
    int NFI = MFI->CreateFixedObject(4, FRI->second, true);
    MBlazeFI->recordReplacement(FRI->first, NFI);

    for (MachineFunction::iterator MB=MF.begin(), ME=MF.end(); MB!=ME; ++MB) {
      MachineBasicBlock::iterator MBB = MB->begin();
      const MachineBasicBlock::iterator MBE = MB->end();

      for (; MBB != MBE; ++MBB) {
        MachineInstr::mop_iterator MIB = MBB->operands_begin();
        const MachineInstr::mop_iterator MIE = MBB->operands_end();

        for (MachineInstr::mop_iterator MII = MIB; MII != MIE; ++MII) {
          if (!MII->isFI() || MII->getIndex() != FRI->first) continue;
          DEBUG(dbgs() << "FOUND FI#" << MII->getIndex() << "\n");
          MII->setIndex(NFI);
        }
      }
    }
  }
}
static void
deriveBodyEquatable_enum_uninhabited_eq(AbstractFunctionDecl *eqDecl) {
  auto parentDC = eqDecl->getDeclContext();
  ASTContext &C = parentDC->getASTContext();

  auto args = eqDecl->getParameters();
  auto aParam = args->get(0);
  auto bParam = args->get(1);

  assert(!cast<EnumDecl>(aParam->getType()->getAnyNominal())->hasCases());

  SmallVector<ASTNode, 1> statements;
  SmallVector<ASTNode, 0> cases;

  // switch (a, b) { }
  auto aRef = new (C) DeclRefExpr(aParam, DeclNameLoc(), /*implicit*/ true);
  auto bRef = new (C) DeclRefExpr(bParam, DeclNameLoc(), /*implicit*/ true);
  auto abExpr = TupleExpr::create(C, SourceLoc(), {aRef, bRef}, {}, {},
                                  SourceLoc(), /*HasTrailingClosure*/ false,
                                  /*implicit*/ true);
  auto switchStmt = SwitchStmt::create(LabeledStmtInfo(), SourceLoc(), abExpr,
                                       SourceLoc(), cases, SourceLoc(), C);
  statements.push_back(switchStmt);

  auto body = BraceStmt::create(C, SourceLoc(), statements, SourceLoc());
  eqDecl->setBody(body);
}
Example #27
0
/// \brief Ensure that the loop preheader dominates all exit blocks.
///
/// This method is used to split exit blocks that have predecessors outside of
/// the loop.
static BasicBlock *rewriteLoopExitBlock(Loop *L, BasicBlock *Exit,
                                        DominatorTree *DT, LoopInfo *LI,
                                        Pass *PP) {
  SmallVector<BasicBlock*, 8> LoopBlocks;
  for (pred_iterator I = pred_begin(Exit), E = pred_end(Exit); I != E; ++I) {
    BasicBlock *P = *I;
    if (L->contains(P)) {
      // Don't do this if the loop is exited via an indirect branch.
      if (isa<IndirectBrInst>(P->getTerminator())) return nullptr;

      LoopBlocks.push_back(P);
    }
  }

  assert(!LoopBlocks.empty() && "No edges coming in from outside the loop?");
  BasicBlock *NewExitBB = nullptr;

  bool PreserveLCSSA = PP->mustPreserveAnalysisID(LCSSAID);

  NewExitBB = SplitBlockPredecessors(Exit, LoopBlocks, ".loopexit", DT, LI,
                                     PreserveLCSSA);
  if (!NewExitBB)
    return nullptr;

  DEBUG(dbgs() << "LoopSimplify: Creating dedicated exit block "
               << NewExitBB->getName() << "\n");
  return NewExitBB;
}
Example #28
0
static bool CheckNakedParmReference(Expr *E, Sema &S) {
  FunctionDecl *Func = dyn_cast<FunctionDecl>(S.CurContext);
  if (!Func)
    return false;
  if (!Func->hasAttr<NakedAttr>())
    return false;

  SmallVector<Expr*, 4> WorkList;
  WorkList.push_back(E);
  while (WorkList.size()) {
    Expr *E = WorkList.pop_back_val();
    if (isa<CXXThisExpr>(E)) {
      S.Diag(E->getLocStart(), diag::err_asm_naked_this_ref);
      S.Diag(Func->getAttr<NakedAttr>()->getLocation(), diag::note_attribute);
      return true;
    }
    if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
      if (isa<ParmVarDecl>(DRE->getDecl())) {
        S.Diag(DRE->getLocStart(), diag::err_asm_naked_parm_ref);
        S.Diag(Func->getAttr<NakedAttr>()->getLocation(), diag::note_attribute);
        return true;
      }
    }
    for (Stmt *Child : E->children()) {
      if (Expr *E = dyn_cast_or_null<Expr>(Child))
        WorkList.push_back(E);
    }
  }
  return false;
}
Example #29
0
void UserValue::extendDef(SlotIndex Idx, unsigned LocNo,
                          LiveRange *LR, const VNInfo *VNI,
                          SmallVectorImpl<SlotIndex> *Kills,
                          LiveIntervals &LIS, MachineDominatorTree &MDT,
                          UserValueScopes &UVS) {
  SmallVector<SlotIndex, 16> Todo;
  Todo.push_back(Idx);
  do {
    SlotIndex Start = Todo.pop_back_val();
    MachineBasicBlock *MBB = LIS.getMBBFromIndex(Start);
    SlotIndex Stop = LIS.getMBBEndIdx(MBB);
    LocMap::iterator I = locInts.find(Start);

    // Limit to VNI's live range.
    bool ToEnd = true;
    if (LR && VNI) {
      LiveInterval::Segment *Segment = LR->getSegmentContaining(Start);
      if (!Segment || Segment->valno != VNI) {
        if (Kills)
          Kills->push_back(Start);
        continue;
      }
      if (Segment->end < Stop)
        Stop = Segment->end, ToEnd = false;
    }

    // There could already be a short def at Start.
    if (I.valid() && I.start() <= Start) {
      // Stop when meeting a different location or an already extended interval.
      Start = Start.getNextSlot();
      if (I.value() != LocNo || I.stop() != Start)
        continue;
      // This is a one-slot placeholder. Just skip it.
      ++I;
    }

    // Limited by the next def.
    if (I.valid() && I.start() < Stop)
      Stop = I.start(), ToEnd = false;
    // Limited by VNI's live range.
    else if (!ToEnd && Kills)
      Kills->push_back(Stop);

    if (Start >= Stop)
      continue;

    I.insert(Start, Stop, LocNo);

    // If we extended to the MBB end, propagate down the dominator tree.
    if (!ToEnd)
      continue;
    const std::vector<MachineDomTreeNode*> &Children =
      MDT.getNode(MBB)->getChildren();
    for (unsigned i = 0, e = Children.size(); i != e; ++i) {
      MachineBasicBlock *MBB = Children[i]->getBlock();
      if (UVS.dominates(MBB))
        Todo.push_back(LIS.getMBBStartIdx(MBB));
    }
  } while (!Todo.empty());
}
Example #30
0
unsigned InlineCostAnalyzer::FunctionInfo::countCodeReductionForAlloca(
    const CodeMetrics &Metrics, Value *V) {
  if (!V->getType()->isPointerTy()) return 0;  // Not a pointer
  unsigned Reduction = 0;
  unsigned SROAReduction = 0;
  bool CanSROAAlloca = true;

  SmallVector<Value *, 4> Worklist;
  Worklist.push_back(V);
  do {
    Value *V = Worklist.pop_back_val();
    for (Value::use_iterator UI = V->use_begin(), E = V->use_end();
         UI != E; ++UI){
      Instruction *I = cast<Instruction>(*UI);

      if (ICmpInst *ICI = dyn_cast<ICmpInst>(I))
        Reduction += countCodeReductionForAllocaICmp(Metrics, ICI);

      if (CanSROAAlloca)
        CanSROAAlloca = countCodeReductionForSROAInst(I, Worklist,
                                                      SROAReduction);
    }
  } while (!Worklist.empty());

  return Reduction + (CanSROAAlloca ? SROAReduction : 0);
}