Пример #1
0
void CodeViewDebug::maybeRecordLocation(DebugLoc DL,
                                        const MachineFunction *MF) {
  // Skip this instruction if it has the same location as the previous one.
  if (DL == CurFn->LastLoc)
    return;

  const DIScope *Scope = DL.get()->getScope();
  if (!Scope)
    return;

  // Skip this line if it is longer than the maximum we can record.
  LineInfo LI(DL.getLine(), DL.getLine(), /*IsStatement=*/true);
  if (LI.getStartLine() != DL.getLine() || LI.isAlwaysStepInto() ||
      LI.isNeverStepInto())
    return;

  ColumnInfo CI(DL.getCol(), /*EndColumn=*/0);
  if (CI.getStartColumn() != DL.getCol())
    return;

  if (!CurFn->HaveLineInfo)
    CurFn->HaveLineInfo = true;
  unsigned FileId = 0;
  if (CurFn->LastLoc.get() && CurFn->LastLoc->getFile() == DL->getFile())
    FileId = CurFn->LastFileId;
  else
    FileId = CurFn->LastFileId = maybeRecordFile(DL->getFile());
  CurFn->LastLoc = DL;

  unsigned FuncId = CurFn->FuncId;
  if (const DILocation *SiteLoc = DL->getInlinedAt()) {
    const DILocation *Loc = DL.get();

    // If this location was actually inlined from somewhere else, give it the ID
    // of the inline call site.
    FuncId =
        getInlineSite(SiteLoc, Loc->getScope()->getSubprogram()).SiteFuncId;

    // Ensure we have links in the tree of inline call sites.
    bool FirstLoc = true;
    while ((SiteLoc = Loc->getInlinedAt())) {
      InlineSite &Site =
          getInlineSite(SiteLoc, Loc->getScope()->getSubprogram());
      if (!FirstLoc)
        addLocIfNotPresent(Site.ChildSites, Loc);
      FirstLoc = false;
      Loc = SiteLoc;
    }
    addLocIfNotPresent(CurFn->ChildSites, Loc);
  }

  OS.EmitCVLocDirective(FuncId, FileId, DL.getLine(), DL.getCol(),
                        /*PrologueEnd=*/false,
                        /*IsStmt=*/false, DL->getFilename());
}
Пример #2
0
void CodeViewDebug::maybeRecordLocation(DebugLoc DL,
                                        const MachineFunction *MF) {
  // Skip this instruction if it has the same location as the previous one.
  if (DL == CurFn->LastLoc)
    return;

  const DIScope *Scope = DL.get()->getScope();
  if (!Scope)
    return;

  // Skip this line if it is longer than the maximum we can record.
  LineInfo LI(DL.getLine(), DL.getLine(), /*IsStatement=*/true);
  if (LI.getStartLine() != DL.getLine() || LI.isAlwaysStepInto() ||
      LI.isNeverStepInto())
    return;

  ColumnInfo CI(DL.getCol(), /*EndColumn=*/0);
  if (CI.getStartColumn() != DL.getCol())
    return;

  if (!CurFn->HaveLineInfo)
    CurFn->HaveLineInfo = true;
  unsigned FileId = 0;
  if (CurFn->LastLoc.get() && CurFn->LastLoc->getFile() == DL->getFile())
    FileId = CurFn->LastFileId;
  else
    FileId = CurFn->LastFileId = maybeRecordFile(DL->getFile());
  CurFn->LastLoc = DL;

  unsigned FuncId = CurFn->FuncId;
  if (const DILocation *Loc = DL->getInlinedAt()) {
    // If this location was actually inlined from somewhere else, give it the ID
    // of the inline call site.
    FuncId = getInlineSite(DL.get()).SiteFuncId;
    // Ensure we have links in the tree of inline call sites.
    const DILocation *ChildLoc = nullptr;
    while (Loc->getInlinedAt()) {
      InlineSite &Site = getInlineSite(Loc);
      if (ChildLoc) {
        // Record the child inline site if not already present.
        auto B = Site.ChildSites.begin(), E = Site.ChildSites.end();
        if (std::find(B, E, Loc) != E)
          break;
        Site.ChildSites.push_back(Loc);
      }
      ChildLoc = Loc;
    }
  }

  Asm->OutStreamer->EmitCVLocDirective(FuncId, FileId, DL.getLine(),
                                       DL.getCol(), /*PrologueEnd=*/false,
                                       /*IsStmt=*/false, DL->getFilename());
}
Пример #3
0
bool DISubprogram::Verify() const {
  auto *N = getRaw();
  if (!N)
    return false;

  if (!isScopeRef(N->getScope()))
    return false;

  if (auto *Op = N->getType())
    if (!isa<MDNode>(Op))
      return false;

  if (!isTypeRef(getContainingType()))
    return false;

  if (isLValueReference() && isRValueReference())
    return false;

  // If a DISubprogram has an llvm::Function*, then scope chains from all
  // instructions within the function should lead to this DISubprogram.
  if (auto *F = getFunction()) {
    for (auto &BB : *F) {
      for (auto &I : BB) {
        DebugLoc DL = I.getDebugLoc();
        if (DL.isUnknown())
          continue;

        MDNode *Scope = nullptr;
        MDNode *IA = nullptr;
        // walk the inlined-at scopes
        while ((IA = DL.getInlinedAt()))
          DL = DebugLoc::getFromDILocation(IA);
        DL.getScopeAndInlinedAt(Scope, IA);
        if (!Scope)
          return false;
        assert(!IA);
        while (!DIDescriptor(Scope).isSubprogram()) {
          DILexicalBlockFile D(Scope);
          Scope = D.isLexicalBlockFile()
                      ? D.getScope()
                      : DebugLoc::getFromDILexicalBlock(Scope).getScope();
          if (!Scope)
            return false;
        }
        if (!DISubprogram(Scope).describes(F))
          return false;
      }
    }
  }

  return true;
}
Пример #4
0
/// updateInlinedAtInfo - Helper function used by fixupLineNumbers to
/// recursively update InlinedAtEntry of a DebugLoc.
static DebugLoc updateInlinedAtInfo(const DebugLoc &DL, 
                                    const DebugLoc &InlinedAtDL,
                                    LLVMContext &Ctx) {
  if (MDNode *IA = DL.getInlinedAt(Ctx)) {
    DebugLoc NewInlinedAtDL 
      = updateInlinedAtInfo(DebugLoc::getFromDILocation(IA), InlinedAtDL, Ctx);
    return DebugLoc::get(DL.getLine(), DL.getCol(), DL.getScope(Ctx),
                         NewInlinedAtDL.getAsMDNode(Ctx));
  }

  return DebugLoc::get(DL.getLine(), DL.getCol(), DL.getScope(Ctx),
                       InlinedAtDL.getAsMDNode(Ctx));
}
Пример #5
0
static void print_source_line(raw_ostream &stream, DebugLoc Loc)
{
    MDNode *inlinedAt = Loc.getInlinedAt(jl_LLVMContext);
    if (inlinedAt != NULL) {
        DebugLoc inlineloc = DebugLoc::getFromDILocation(inlinedAt);
        stream << "Source line: " << inlineloc.getLine() << "\n";

        DILexicalBlockFile innerscope = DILexicalBlockFile(Loc.getScope(jl_LLVMContext));
        stream << "Source line: [inline] " << innerscope.getFilename().str().c_str() << ':' << Loc.getLine() << "\n";
    }
    else {
        stream << "Source line: " << Loc.getLine() << "\n";
    }
}
Пример #6
0
bool DISubprogram::Verify() const {
  if (!isSubprogram())
    return false;

  // Make sure context @ field 2 is a ScopeRef and type @ field 3 is a MDNode.
  if (!fieldIsScopeRef(DbgNode, 2))
    return false;
  if (!fieldIsMDNode(DbgNode, 3))
    return false;
  // Containing type @ field 4.
  if (!fieldIsTypeRef(DbgNode, 4))
    return false;

  // A subprogram can't be both & and &&.
  if (isLValueReference() && isRValueReference())
    return false;

  // If a DISubprogram has an llvm::Function*, then scope chains from all
  // instructions within the function should lead to this DISubprogram.
  if (auto *F = getFunction()) {
    for (auto &BB : *F) {
      for (auto &I : BB) {
        DebugLoc DL = I.getDebugLoc();
        if (DL.isUnknown())
          continue;

        MDNode *Scope = nullptr;
        MDNode *IA = nullptr;
        // walk the inlined-at scopes
        while ((IA = DL.getInlinedAt()))
          DL = DebugLoc::getFromDILocation(IA);
        DL.getScopeAndInlinedAt(Scope, IA);
        if (!Scope)
          return false;
        assert(!IA);
        while (!DIDescriptor(Scope).isSubprogram()) {
          DILexicalBlockFile D(Scope);
          Scope = D.isLexicalBlockFile()
                      ? D.getScope()
                      : DebugLoc::getFromDILexicalBlock(Scope).getScope();
          if (!Scope)
            return false;
        }
        if (!DISubprogram(Scope).describes(F))
          return false;
      }
    }
  }
  return DbgNode->getNumOperands() == 9 && getNumHeaderFields() == 12;
}
Пример #7
0
// Tries to remove a sanity check; returns true if it worked.
bool AsapPass::optimizeCheckAway(llvm::Instruction *Inst) {
    BranchInst *BI = cast<BranchInst>(Inst);
    assert(BI->isConditional() && "Sanity check must be conditional branch.");
    
    unsigned int RegularBranch = getRegularBranch(BI, SCI);
    
    bool Changed = false;
    if (RegularBranch == 0) {
        BI->setCondition(ConstantInt::getTrue(Inst->getContext()));
        Changed = true;
    } else if (RegularBranch == 1) {
        BI->setCondition(ConstantInt::getFalse(Inst->getContext()));
        Changed = true;
    } else {
        // This can happen, e.g., in the following case:
        //     array[-1] = a + b;
        // is transformed into
        //     if (a + b overflows)
        //         report_overflow()
        //     else
        //         report_index_out_of_bounds();
        // In this case, removing the sanity check does not help much, so we
        // just do nothing.
        // Thanks to Will Dietz for his explanation at
        // http://lists.cs.uiuc.edu/pipermail/llvmdev/2014-April/071958.html
        dbgs() << "Warning: Sanity check with no regular branch found.\n";
        dbgs() << "The sanity check has been kept intact.\n";
    }
    
    if (PrintRemovedChecks && Changed) {
        DebugLoc DL = getSanityCheckDebugLoc(BI, RegularBranch);
        printDebugLoc(DL, BI->getContext(), dbgs());
        dbgs() << ": SanityCheck with cost ";
        dbgs() << *BI->getMetadata("cost")->getOperand(0);

        if (MDNode *IA = DL.getInlinedAt()) {
            dbgs() << " (inlined at ";
            printDebugLoc(DebugLoc(IA), BI->getContext(), dbgs());
            dbgs() << ")";
        }

        BasicBlock *Succ = BI->getSuccessor(RegularBranch == 0 ? 1 : 0);
        if (const CallInst *CI = SCI->findSanityCheckCall(Succ)) {
            dbgs() << " " << CI->getCalledFunction()->getName();
        }
        dbgs() << "\n";
    }

    return Changed;
}
Пример #8
0
/// processModule - Process entire module and collect debug info.
void DebugInfoFinder::processModule(Module &M) {
  if (NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu"))
    for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i)
      addCompileUnit(DICompileUnit(CU_Nodes->getOperand(i)));

  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
    for (Function::iterator FI = (*I).begin(), FE = (*I).end(); FI != FE; ++FI)
      for (BasicBlock::iterator BI = (*FI).begin(), BE = (*FI).end(); BI != BE;
           ++BI) {
        if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI))
          processDeclare(DDI);

        DebugLoc Loc = BI->getDebugLoc();
        if (Loc.isUnknown())
          continue;

        LLVMContext &Ctx = BI->getContext();
        DIDescriptor Scope(Loc.getScope(Ctx));

        if (Scope.isCompileUnit())
          addCompileUnit(DICompileUnit(Scope));
        else if (Scope.isSubprogram())
          processSubprogram(DISubprogram(Scope));
        else if (Scope.isLexicalBlock())
          processLexicalBlock(DILexicalBlock(Scope));

        if (MDNode *IA = Loc.getInlinedAt(Ctx))
          processLocation(DILocation(IA));
      }

  if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.gv")) {
    for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
      DIGlobalVariable DIG(cast<MDNode>(NMD->getOperand(i)));
      if (addGlobalVariable(DIG)) {
        if (DIG.getVersion() <= LLVMDebugVersion10)
          addCompileUnit(DIG.getCompileUnit());
        processType(DIG.getType());
      }
    }
  }

  if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.sp"))
    for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i)
      processSubprogram(DISubprogram(NMD->getOperand(i)));
}
Пример #9
0
static void printDebugLoc(DebugLoc DL, raw_ostream &CommentOS,
                          const LLVMContext &Ctx) {
  if (!DL.isUnknown()) { // Print source line info.
    DIScope Scope(DL.getScope(Ctx));
    assert(Scope.isScope() && "Scope of a DebugLoc should be a DIScope.");
    // Omit the directory, because it's likely to be long and uninteresting.
    CommentOS << Scope.getFilename();
    CommentOS << ':' << DL.getLine();
    if (DL.getCol() != 0)
      CommentOS << ':' << DL.getCol();
    DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(DL.getInlinedAt(Ctx));
    if (!InlinedAtDL.isUnknown()) {
      CommentOS << " @[ ";
      printDebugLoc(InlinedAtDL, CommentOS, Ctx);
      CommentOS << " ]";
    }
  }
}
Пример #10
0
static void printDebugLoc(DebugLoc DL, raw_ostream &CommentOS,
                          const LLVMContext &Ctx) {
  if (!DL)
    return;

  auto *Scope = cast<MDScope>(DL.getScope());
  // Omit the directory, because it's likely to be long and uninteresting.
  CommentOS << Scope->getFilename();
  CommentOS << ':' << DL.getLine();
  if (DL.getCol() != 0)
    CommentOS << ':' << DL.getCol();

  DebugLoc InlinedAtDL = DL.getInlinedAt();
  if (!InlinedAtDL)
    return;

  CommentOS << " @[ ";
  printDebugLoc(InlinedAtDL, CommentOS, Ctx);
  CommentOS << " ]";
}
Пример #11
0
static void printDebugLoc(DebugLoc DL, raw_ostream &CommentOS,
                          const LLVMContext &Ctx) {
  if (!DL)
    return;

  DIScope Scope(DL.getScope());
  assert(Scope.isScope() && "Scope of a DebugLoc should be a DIScope.");
  // Omit the directory, because it's likely to be long and uninteresting.
  CommentOS << Scope.getFilename();
  CommentOS << ':' << DL.getLine();
  if (DL.getCol() != 0)
    CommentOS << ':' << DL.getCol();

  DebugLoc InlinedAtDL = DL.getInlinedAt();
  if (!InlinedAtDL)
    return;

  CommentOS << " @[ ";
  printDebugLoc(InlinedAtDL, CommentOS, Ctx);
  CommentOS << " ]";
}