Commit 238b4c16 by Jim Stichnoth

Subzero: Change -asm-verbose output to print more useful info.

Frame offsets for variables are emitted using a symbolic name based on the variable's name. This makes it a bit easier to digest the asm code. For example, if variable Foo gets an esp offset 24, asm like this: ... 24(%esp) ... will instead be emitted like this: lv$Foo = 24 ... ... lv$Foo(%esp) ... Predecessor labels are printed for each basic block. Loop nest depth is printed for each basic block. (Would be nice if we had loop header info as well.) BUG= none R=jpp@chromium.org Review URL: https://codereview.chromium.org/1377323002 .
parent 07af2ac7
......@@ -743,6 +743,14 @@ void Cfg::emit() {
emitTextHeader(MangledName, Ctx, Asm);
deleteJumpTableInsts();
if (Ctx->getFlags().getDecorateAsm()) {
for (Variable *Var : getVariables()) {
if (Var->getStackOffset()) {
Str << "\t" << Var->getSymbolicStackOffset(this) << " = "
<< Var->getStackOffset() << "\n";
}
}
}
for (CfgNode *Node : Nodes) {
if (NeedSandboxing && Node->needsAlignment()) {
Str << "\t" << Asm->getAlignDirective() << " "
......
......@@ -978,7 +978,7 @@ void CfgNode::emit(Cfg *Func) const {
Func->setCurrentNode(this);
Ostream &Str = Func->getContext()->getStrEmit();
Liveness *Liveness = Func->getLiveness();
bool DecorateAsm =
const bool DecorateAsm =
Liveness && Func->getContext()->getFlags().getDecorateAsm();
Str << getAsmName() << ":\n";
// LiveRegCount keeps track of the number of currently live variables that
......@@ -989,6 +989,20 @@ void CfgNode::emit(Cfg *Func) const {
if (DecorateAsm) {
constexpr bool IsLiveIn = true;
emitRegisterUsage(Str, Func, this, IsLiveIn, LiveRegCount);
if (getInEdges().size()) {
Str << "\t\t\t\t# preds=";
bool First = true;
for (CfgNode *I : getInEdges()) {
if (!First)
Str << ",";
First = false;
Str << I->getAsmName();
}
Str << "\n";
}
if (getLoopNestDepth()) {
Str << "\t\t\t\t# loop depth=" << getLoopNestDepth() << "\n";
}
}
for (const Inst &I : Phis) {
......
......@@ -442,6 +442,11 @@ public:
int32_t getStackOffset() const { return StackOffset; }
void setStackOffset(int32_t Offset) { StackOffset = Offset; }
/// Returns the variable's stack offset in symbolic form, to improve
/// readability in DecorateAsm mode.
IceString getSymbolicStackOffset(const Cfg *Func) const {
return "lv$" + getName(Func);
}
static const int32_t NoRegister = -1;
bool hasReg() const { return getRegNum() != NoRegister; }
......
......@@ -746,15 +746,35 @@ void TargetX86Base<Machine>::emitVariable(const Variable *Var) const {
if (Var->mustHaveReg()) {
llvm_unreachable("Infinite-weight Variable has no register assigned");
}
int32_t Offset = Var->getStackOffset();
const int32_t Offset = Var->getStackOffset();
int32_t OffsetAdj = 0;
int32_t BaseRegNum = Var->getBaseRegNum();
if (BaseRegNum == Variable::NoRegister) {
BaseRegNum = getFrameOrStackReg();
if (!hasFramePointer())
Offset += getStackAdjustment();
OffsetAdj = getStackAdjustment();
}
// Print in the form "OffsetAdj+Offset(%reg)", taking care that:
// - OffsetAdj may be 0
// - Offset is never printed when it is 0
// - Offset may be positive or symbolic, so a "+" might be needed
// Only print nonzero OffsetAdj.
if (OffsetAdj) {
Str << OffsetAdj;
}
const bool DecorateAsm = Func->getContext()->getFlags().getDecorateAsm();
// Only print Offset when it is nonzero, regardless of DecorateAsm.
if (Offset) {
if (OffsetAdj && (DecorateAsm || Offset > 0)) {
Str << "+";
}
if (DecorateAsm) {
Str << Var->getSymbolicStackOffset(Func);
} else {
Str << Offset;
}
}
if (Offset)
Str << Offset;
const Type FrameSPTy = Traits::WordType;
Str << "(%" << getRegName(BaseRegNum, FrameSPTy) << ")";
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment