[llvm-commits] [llvm] r54868 - /llvm/trunk/lib/VMCore/AsmWriter.cpp
Chris Lattner
sabre at nondot.org
Sat Aug 16 21:40:13 PDT 2008
Author: lattner
Date: Sat Aug 16 23:40:13 2008
New Revision: 54868
URL: http://llvm.org/viewvc/llvm-project?rev=54868&view=rev
Log:
avoid string thrashing when formatting names in output. This
speeds up release-asserts llvm-dis on kc++ from 1.86s to 1.04s (~79%)
Modified:
llvm/trunk/lib/VMCore/AsmWriter.cpp
Modified: llvm/trunk/lib/VMCore/AsmWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AsmWriter.cpp?rev=54868&r1=54867&r2=54868&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/AsmWriter.cpp (original)
+++ llvm/trunk/lib/VMCore/AsmWriter.cpp Sat Aug 16 23:40:13 2008
@@ -211,6 +211,72 @@
}
}
+/// PrintLLVMName - Turn the specified name into an 'LLVM name', which is either
+/// prefixed with % (if the string only contains simple characters) or is
+/// surrounded with ""'s (if it has special chars in it). Print it out.
+static void PrintLLVMName(std::ostream &OS, const ValueName *Name,
+ PrefixType Prefix) {
+ assert(Name && "Cannot get empty name!");
+ switch (Prefix) {
+ default: assert(0 && "Bad prefix!");
+ case GlobalPrefix: OS << '@'; break;
+ case LabelPrefix: break;
+ case LocalPrefix: OS << '%'; break;
+ }
+
+ // Scan the name to see if it needs quotes first.
+ const char *NameStr = Name->getKeyData();
+ unsigned NameLen = Name->getKeyLength();
+
+ bool NeedsQuotes = NameStr[0] >= '0' && NameStr[0] <= '9';
+ if (!NeedsQuotes) {
+ for (unsigned i = 0; i != NameLen; ++i) {
+ char C = NameStr[i];
+ if (!isalnum(C) && C != '-' && C != '.' && C != '_') {
+ NeedsQuotes = true;
+ break;
+ }
+ }
+ }
+
+ // If we didn't need any quotes, just write out the name in one blast.
+ if (!NeedsQuotes) {
+ OS.write(NameStr, NameLen);
+ return;
+ }
+
+ // Okay, we need quotes. Output the quotes and escape any scary characters as
+ // needed.
+ OS << '"';
+ for (unsigned i = 0; i != NameLen; ++i) {
+ char C = NameStr[i];
+ assert(C != '"' && "Illegal character in LLVM value name!");
+ if (C == '\\') {
+ OS << "\\\\";
+ } else if (isprint(C)) {
+ OS << C;
+ } else {
+ OS << "\\";
+ char hex1 = (C >> 4) & 0x0F;
+ if (hex1 < 10)
+ OS << (hex1 + '0');
+ else
+ OS << (hex1 - 10 + 'A');
+ char hex2 = C & 0x0F;
+ if (hex2 < 10)
+ OS << (hex2 + '0');
+ else
+ OS << (hex2 - 10 + 'A');
+ }
+ }
+ OS << '"';
+}
+
+static void PrintLLVMName(std::ostream &OS, const Value *V) {
+ PrintLLVMName(OS, V->getValueName(),
+ isa<GlobalValue>(V) ? GlobalPrefix : LocalPrefix);
+}
+
/// fillTypeNameTable - If the module has a symbol table, take all global types
/// and stuff their names into the TypeNames map.
@@ -626,25 +692,35 @@
std::map<const Type*, std::string> &TypeTable,
SlotMachine *Machine) {
Out << ' ';
- if (V->hasName())
- Out << getLLVMName(V->getName(),
- isa<GlobalValue>(V) ? GlobalPrefix : LocalPrefix);
- else {
- const Constant *CV = dyn_cast<Constant>(V);
- if (CV && !isa<GlobalValue>(CV)) {
- WriteConstantInt(Out, CV, TypeTable, Machine);
- } else if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
- Out << "asm ";
- if (IA->hasSideEffects())
- Out << "sideeffect ";
- Out << '"';
- PrintEscapedString(IA->getAsmString(), Out);
- Out << "\", \"";
- PrintEscapedString(IA->getConstraintString(), Out);
- Out << '"';
+ if (V->hasName()) {
+ PrintLLVMName(Out, V);
+ return;
+ }
+
+ const Constant *CV = dyn_cast<Constant>(V);
+ if (CV && !isa<GlobalValue>(CV)) {
+ WriteConstantInt(Out, CV, TypeTable, Machine);
+ } else if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
+ Out << "asm ";
+ if (IA->hasSideEffects())
+ Out << "sideeffect ";
+ Out << '"';
+ PrintEscapedString(IA->getAsmString(), Out);
+ Out << "\", \"";
+ PrintEscapedString(IA->getConstraintString(), Out);
+ Out << '"';
+ } else {
+ char Prefix = '%';
+ int Slot;
+ if (Machine) {
+ if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
+ Slot = Machine->getGlobalSlot(GV);
+ Prefix = '@';
+ } else {
+ Slot = Machine->getLocalSlot(V);
+ }
} else {
- char Prefix = '%';
- int Slot;
+ Machine = createSlotMachine(V);
if (Machine) {
if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
Slot = Machine->getGlobalSlot(GV);
@@ -653,24 +729,14 @@
Slot = Machine->getLocalSlot(V);
}
} else {
- Machine = createSlotMachine(V);
- if (Machine) {
- if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
- Slot = Machine->getGlobalSlot(GV);
- Prefix = '@';
- } else {
- Slot = Machine->getLocalSlot(V);
- }
- } else {
- Slot = -1;
- }
- delete Machine;
+ Slot = -1;
}
- if (Slot != -1)
- Out << Prefix << Slot;
- else
- Out << "<badref>";
+ delete Machine;
}
+ if (Slot != -1)
+ Out << Prefix << Slot;
+ else
+ Out << "<badref>";
}
}
@@ -900,7 +966,10 @@
}
void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
- if (GV->hasName()) Out << getLLVMName(GV->getName(), GlobalPrefix) << " = ";
+ if (GV->hasName()) {
+ PrintLLVMName(Out, GV);
+ Out << " = ";
+ }
if (!GV->hasInitializer()) {
switch (GV->getLinkage()) {
@@ -935,11 +1004,8 @@
Out << (GV->isConstant() ? "constant " : "global ");
printType(GV->getType()->getElementType());
- if (GV->hasInitializer()) {
- Constant* C = cast<Constant>(GV->getInitializer());
- assert(C && "GlobalVar initializer isn't constant?");
+ if (GV->hasInitializer())
writeOperand(GV->getInitializer(), false);
- }
if (unsigned AddressSpace = GV->getType()->getAddressSpace())
Out << " addrspace(" << AddressSpace << ") ";
@@ -957,8 +1023,10 @@
// Don't crash when dumping partially built GA
if (!GA->hasName())
Out << "<<nameless>> = ";
- else
- Out << getLLVMName(GA->getName(), GlobalPrefix) << " = ";
+ else {
+ PrintLLVMName(Out, GA);
+ Out << " = ";
+ }
switch (GA->getVisibility()) {
default: assert(0 && "Invalid visibility style!");
case GlobalValue::DefaultVisibility: break;
@@ -980,18 +1048,20 @@
if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Aliasee)) {
printType(GV->getType());
- Out << " " << getLLVMName(GV->getName(), GlobalPrefix);
+ Out << ' ';
+ PrintLLVMName(Out, GV);
} else if (const Function *F = dyn_cast<Function>(Aliasee)) {
printType(F->getFunctionType());
Out << "* ";
- if (!F->getName().empty())
- Out << getLLVMName(F->getName(), GlobalPrefix);
+ if (!F->hasName())
+ PrintLLVMName(Out, F);
else
Out << "@\"\"";
} else if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(Aliasee)) {
printType(GA->getType());
- Out << " " << getLLVMName(GA->getName(), GlobalPrefix);
+ Out << " ";
+ PrintLLVMName(Out, GA);
} else {
const ConstantExpr *CE = 0;
if ((CE = dyn_cast<ConstantExpr>(Aliasee)) &&
@@ -1067,7 +1137,7 @@
const PAListPtr &Attrs = F->getParamAttrs();
printType(F->getReturnType()) << ' ';
if (!F->getName().empty())
- Out << getLLVMName(F->getName(), GlobalPrefix);
+ PrintLLVMName(Out, F);
else
Out << "@\"\"";
Out << '(';
@@ -1144,15 +1214,19 @@
Out << ' ' << ParamAttr::getAsString(Attrs);
// Output name, if available...
- if (Arg->hasName())
- Out << ' ' << getLLVMName(Arg->getName(), LocalPrefix);
+ if (Arg->hasName()) {
+ Out << ' ';
+ PrintLLVMName(Out, Arg);
+ }
}
/// printBasicBlock - This member is called for each basic block in a method.
///
void AssemblyWriter::printBasicBlock(const BasicBlock *BB) {
if (BB->hasName()) { // Print out the label if it exists...
- Out << "\n" << getLLVMName(BB->getName(), LabelPrefix) << ':';
+ Out << "\n";
+ PrintLLVMName(Out, BB->getValueName(), LabelPrefix);
+ Out << ':';
} else if (!BB->use_empty()) { // Don't print block # of no uses...
Out << "\n; <label>:";
int Slot = Machine.getLocalSlot(BB);
@@ -1223,8 +1297,10 @@
Out << "\t";
// Print out name if it exists...
- if (I.hasName())
- Out << getLLVMName(I.getName(), LocalPrefix) << " = ";
+ if (I.hasName()) {
+ PrintLLVMName(Out, &I);
+ Out << " = ";
+ }
// If this is a volatile load or store, print out the volatile marker.
if ((isa<LoadInst>(I) && cast<LoadInst>(I).isVolatile()) ||
@@ -1654,13 +1730,13 @@
/// CreateSlot - Create a new slot for the specified value if it has no name.
void SlotMachine::CreateFunctionSlot(const Value *V) {
- const Type *VTy = V->getType();
- assert(VTy != Type::VoidTy && !V->hasName() && "Doesn't need a slot!");
+ assert(V->getType() != Type::VoidTy && !V->hasName() &&
+ "Doesn't need a slot!");
unsigned DestSlot = fNext++;
fMap[V] = DestSlot;
// G = Global, F = Function, o = other
- SC_DEBUG(" Inserting value [" << VTy << "] = " << V << " slot=" <<
+ SC_DEBUG(" Inserting value [" << V->getType() << "] = " << V << " slot=" <<
DestSlot << " [o]\n");
}
More information about the llvm-commits
mailing list