strange dbgs() behavior: unable to print floats in machine backend


I am trying to debug my backend, and observe very strange behavior with dbgs():

In the IfConverter, I have added two debugging lines that print floating-point numbers for the sake of demonstration that such printing works fine.

bool MeetIfcvtSizeLimit(MachineBasicBlock &BB,
                            unsigned Cycle, unsigned Extra,
                            const BranchProbability &Prediction) const {

                dbgs() << "OOPS " << 1.14 << "\n";
                bool flag = Cycle > 0 && TII->isProfitableToIfCvt(BB, Cycle, Extra,
                dbgs() << "OOPS " << 1.15 << "\n";
      return flag;

This method invokes the backend method

bool ADRESInstrInfo::isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles,
                                         const BranchProbability &Probability) const {
  dbgs() << "OOPS " << 1.16 << "\n";

This invocation works as it should (verified with gdb). But when I execute this code fragment, I get

OOPS 1.140000e+00
OOPS %physreg1
OOPS 1.150000e+00

So suddenly in the machine backend, the dbgs() ostream (which is still the very same ostream as in the IfConverter, I checked the address with gdb) prints floating point numbers as if they are physical registers. Any idea what is going on or how I can force floating-point numbers to be printed in the backend code? I want to do that to tune my if-predication heuristics ...

By the way, when I step through the isProfitableToIfCvt method, rather than invoking a <<-operator in an ostream class, the constructor of the Twine class is invoked ...


Bjorn De Sutter
Computer Systems Lab
Ghent University


that solved my problem on trunk as well, thanks. Strange that you have to include this though.


Can you try making the constructor “explicit” for PrintReg in include/llvm/Target/TargetRegisterInfo.h. I think you were getting an implicit conversion there which should probably be fixed anyway.

Hi Craig,

I updated from the trunk some minutes ago, and thus got the “explicit”. PrintReg constructor. When I do not include raw_ostream.h after including Debug.h in the backend cpp files, I now get compilation errors, not only when trying to print floats but also in other places. For example, for the code

bool ADRESRegisterInfo::hasReservedCallFrame(const MachineFunction &MF) const {
dbgs() << "hasReservedCallFrame() = " << !MF.getFrameInfo()->hasVarSizedObjects() << “\n”;
return !MF.getFrameInfo()->hasVarSizedObjects();

I get

llvm[0]: Compiling ADRESRegisterInfo.cpp for Debug+Asserts build
/work/llvm/trunk/llvm/lib/Target/ADRES/ADRESRegisterInfo.cpp: In member function ‘bool llvm::ADRESRegisterInfo::hasReservedCallFrame(const llvm::MachineFunction&) const’:
/work/llvm/trunk/llvm/lib/Target/ADRES/ADRESRegisterInfo.cpp:38:83: error: no match for ‘operator<<’ in ‘llvm::operator<<((* & llvm::dbgs()), (* & llvm::Twine(((const char*)"hasReservedCallFrame() = ")))) << !(& MF)->llvm::MachineFunction::getFrameInfo()->llvm::MachineFrameInfo::hasVarSizedObjects()’
/work/llvm/trunk/llvm/lib/Target/ADRES/ADRESRegisterInfo.cpp:38:83: note: candidates are:
/work/llvm/trunk/llvm/include/llvm/Type.h:412:28: note: llvm::raw_ostream& llvm::operator<<(llvm::raw_ostream&, llvm::Type&)
/work/llvm/trunk/llvm/include/llvm/Type.h:412:28: note: no known conversion for argument 2 from ‘bool’ to ‘llvm::Type&’
/work/llvm/trunk/llvm/include/llvm/ADT/Twine.h:516:23: note: llvm::raw_ostream& llvm::operator<<(llvm::raw_ostream&, const llvm::Twine&)
/work/llvm/trunk/llvm/include/llvm/ADT/Twine.h:516:23: note: no known conversion for argument 2 from ‘bool’ to ‘const llvm::Twine&’
/work/llvm/trunk/llvm/include/llvm/CodeGen/MachineOperand.h:685:21: note: llvm::raw_ostream& llvm::operator<<(llvm::raw_ostream&, const llvm::MachineOperand&)
/work/llvm/trunk/llvm/include/llvm/CodeGen/MachineOperand.h:685:21: note: no known conversion for argument 2 from ‘bool’ to ‘const llvm::MachineOperand&’
/work/llvm/trunk/llvm/include/llvm/Value.h:320:21: note: llvm::raw_ostream& llvm::operator<<(llvm::raw_ostream&, const llvm::Value&)
/work/llvm/trunk/llvm/include/llvm/Value.h:320:21: note: no known conversion for argument 2 from ‘bool’ to ‘const llvm::Value&’
/work/llvm/trunk/llvm/include/llvm/CodeGen/MachineInstr.h:1017:21: note: llvm::raw_ostream& llvm::operator<<(llvm::raw_ostream&, const llvm::MachineInstr&)
/work/llvm/trunk/llvm/include/llvm/CodeGen/MachineInstr.h:1017:21: note: no known conversion for argument 2 from ‘bool’ to ‘const llvm::MachineInstr&’
/work/llvm/trunk/llvm/include/llvm/CodeGen/MachineBasicBlock.h:621:14: note: llvm::raw_ostream& llvm::operator<<(llvm::raw_ostream&, const llvm::MachineBasicBlock&)
/work/llvm/trunk/llvm/include/llvm/CodeGen/MachineBasicBlock.h:621:14: note: no known conversion for argument 2 from ‘bool’ to ‘const llvm::MachineBasicBlock&’
/work/llvm/trunk/llvm/include/llvm/Target/TargetRegisterInfo.h:885:28: note: llvm::raw_ostream& llvm::operator<<(llvm::raw_ostream&, const llvm::PrintReg&)
/work/llvm/trunk/llvm/include/llvm/Target/TargetRegisterInfo.h:885:28: note: no known conversion for argument 2 from ‘bool’ to ‘const llvm::PrintReg&’
/work/llvm/trunk/llvm/include/llvm/Target/TargetRegisterInfo.h:908:28: note: llvm::raw_ostream& llvm::operator<<(llvm::raw_ostream&, const llvm::PrintRegUnit&)
/work/llvm/trunk/llvm/include/llvm/Target/TargetRegisterInfo.h:908:28: note: no known conversion for argument 2 from ‘bool’ to ‘const llvm::PrintRegUnit&’

Including the raw_ostream.h fixes this, but that is not a thing I should have to do, right?



The explicit fix was just to prevent the build from succeeding and doing something unexpected. raw_ostream.h isn’t automatically included everywhere so its not unexpected that you would need to include to print in a file that wasn’t previously printing.