[llvm-commits] [lld] r171530 - /lld/trunk/lib/Passes/GOTPass.cpp
Michael J. Spencer
bigcheesegs at gmail.com
Fri Jan 4 13:18:13 PST 2013
Author: mspencer
Date: Fri Jan 4 15:18:13 2013
New Revision: 171530
URL: http://llvm.org/viewvc/llvm-project?rev=171530&view=rev
Log:
[Passes][GOT] Fix style.
Modified:
lld/trunk/lib/Passes/GOTPass.cpp
Modified: lld/trunk/lib/Passes/GOTPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Passes/GOTPass.cpp?rev=171530&r1=171529&r2=171530&view=diff
==============================================================================
--- lld/trunk/lib/Passes/GOTPass.cpp (original)
+++ lld/trunk/lib/Passes/GOTPass.cpp Fri Jan 4 15:18:13 2013
@@ -6,29 +6,30 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This linker pass transforms all GOT kind references to real references.
-// That is, in assembly you can write something like:
-// movq foo at GOTPCREL(%rip), %rax
-// which means you want to load a pointer to "foo" out of the GOT (global
-// Offsets Table). In the object file, the Atom containing this instruction
-// has a Reference whose target is an Atom named "foo" and the Reference
-// kind is a GOT load. The linker needs to instantiate a pointer sized
-// GOT entry. This is done be creating a GOT Atom to represent that pointer
-// sized data in this pass, and altering the Atom graph so the Reference now
-// points to the GOT Atom entry (corresponding to "foo") and changing the
-// Reference Kind to reflect it is now pointing to a GOT entry (rather
-// then needing a GOT entry).
-//
-// There is one optimization the linker can do here. If the target of the GOT
-// is in the same linkage unit and does not need to be interposable, and
-// the GOT use is just a load (not some other operation), this pass can
-// transform that load into an LEA (add). This optimizes away one memory load
-// which at runtime that could stall the pipeline. This optimization only works
-// for architectures in which a (GOT) load instruction can be change to an
-// LEA instruction that is the same size. The method isGOTAccess()
-// should only return true for "canBypassGOT" if this optimization is supported.
-//
+///
+/// \file
+/// This linker pass transforms all GOT kind references to real references.
+/// That is, in assembly you can write something like:
+/// movq foo at GOTPCREL(%rip), %rax
+/// which means you want to load a pointer to "foo" out of the GOT (global
+/// Offsets Table). In the object file, the Atom containing this instruction
+/// has a Reference whose target is an Atom named "foo" and the Reference
+/// kind is a GOT load. The linker needs to instantiate a pointer sized
+/// GOT entry. This is done be creating a GOT Atom to represent that pointer
+/// sized data in this pass, and altering the Atom graph so the Reference now
+/// points to the GOT Atom entry (corresponding to "foo") and changing the
+/// Reference Kind to reflect it is now pointing to a GOT entry (rather
+/// then needing a GOT entry).
+///
+/// There is one optimization the linker can do here. If the target of the GOT
+/// is in the same linkage unit and does not need to be interposable, and
+/// the GOT use is just a load (not some other operation), this pass can
+/// transform that load into an LEA (add). This optimizes away one memory load
+/// which at runtime that could stall the pipeline. This optimization only
+/// works for architectures in which a (GOT) load instruction can be change to
+/// an LEA instruction that is the same size. The method isGOTAccess() should
+/// only return true for "canBypassGOT" if this optimization is supported.
+///
//===----------------------------------------------------------------------===//
#include "lld/Core/DefinedAtom.h"
@@ -39,72 +40,63 @@
#include "llvm/ADT/DenseMap.h"
namespace lld {
-
void GOTPass::perform(File& mergedFile) {
// Use map so all pointers to same symbol use same GOT entry.
llvm::DenseMap<const Atom*, const DefinedAtom*> targetToGOT;
-
+
// Scan all references in all atoms.
for(const DefinedAtom *atom : mergedFile.defined()) {
for (const Reference *ref : *atom) {
// Look at instructions accessing the GOT.
bool canBypassGOT;
- if ( this->isGOTAccess(ref->kind(), canBypassGOT) ) {
+ if (isGOTAccess(ref->kind(), canBypassGOT)) {
const Atom* target = ref->target();
assert(target != nullptr);
const DefinedAtom* defTarget = dyn_cast<DefinedAtom>(target);
bool replaceTargetWithGOTAtom = false;
- if ( target->definition() == Atom::definitionSharedLibrary ) {
+ if (target->definition() == Atom::definitionSharedLibrary) {
// Accesses to shared library symbols must go through GOT.
replaceTargetWithGOTAtom = true;
- }
- else if ( (defTarget != nullptr)
- && (defTarget->interposable() != DefinedAtom::interposeNo) ) {
- // Accesses to interposable symbols in same linkage unit
+ } else if ((defTarget != nullptr) &&
+ (defTarget->interposable() != DefinedAtom::interposeNo)) {
+ // Accesses to interposable symbols in same linkage unit
// must also go through GOT.
assert(defTarget->scope() != DefinedAtom::scopeTranslationUnit);
replaceTargetWithGOTAtom = true;
- }
- else {
+ } else {
// Target does not require indirection. So, if instruction allows
// GOT to be by-passed, do that optimization and don't create
// GOT entry.
replaceTargetWithGOTAtom = !canBypassGOT;
}
- if ( replaceTargetWithGOTAtom ) {
+ if (replaceTargetWithGOTAtom) {
// Replace the target with a reference to a GOT entry.
const DefinedAtom* gotEntry = nullptr;
auto pos = targetToGOT.find(target);
- if ( pos == targetToGOT.end() ) {
+ if (pos == targetToGOT.end()) {
// This is no existing GOT entry. Create a new one.
- gotEntry = this->makeGOTEntry(*target);
+ gotEntry = makeGOTEntry(*target);
assert(gotEntry != nullptr);
assert(gotEntry->contentType() == DefinedAtom::typeGOT);
targetToGOT[target] = gotEntry;
- }
- else {
+ } else {
// Reuse an existing GOT entry.
gotEntry = pos->second;
assert(gotEntry != nullptr);
}
// Switch reference to GOT atom.
- (const_cast<Reference*>(ref))->setTarget(gotEntry);
+ const_cast<Reference*>(ref)->setTarget(gotEntry);
}
// Update reference kind to reflect
// that target is now a GOT entry or a direct accesss.
- this->updateReferenceToGOT(ref, replaceTargetWithGOTAtom);
+ updateReferenceToGOT(ref, replaceTargetWithGOTAtom);
}
}
}
-
+
// add all created GOT Atoms to master file
- for (auto it=targetToGOT.begin(), end=targetToGOT.end(); it != end; ++it) {
- mergedFile.addAtom(*it->second);
+ for (auto &it : targetToGOT) {
+ mergedFile.addAtom(*it.second);
}
-
-
}
-
-
-
}
More information about the llvm-commits
mailing list